From aa8830f57a63db5408126fbecdec58c18c06b27d Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Mon, 1 May 2023 13:02:16 -0400 Subject: [PATCH 01/34] Feature: Filter engine build menu by name and NewGRF extra text (#10519) --- src/build_vehicle_gui.cpp | 115 ++++++++++++++++++++++++++--- src/widgets/build_vehicle_widget.h | 1 + 2 files changed, 104 insertions(+), 12 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 6886b95bb8..d7b4ea6930 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -34,6 +34,9 @@ #include "train_cmd.h" #include "vehicle_cmd.h" #include "zoom_func.h" +#include "querystring_gui.h" +#include "stringfilter_type.h" +#include "hotkeys.h" #include "widgets/build_vehicle_widget.h" @@ -69,6 +72,7 @@ static const NWidgetPart _nested_build_vehicle_widgets[] = { NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BV_SHOW_HIDDEN_ENGINES), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_BV_CARGO_FILTER_DROPDOWN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA), EndContainer(), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_BV_FILTER), SetMinimalSize(128, 0), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), EndContainer(), EndContainer(), /* Vehicle list. */ @@ -854,31 +858,44 @@ static int DrawAircraftPurchaseInfo(int left, int right, int y, EngineID engine_ return y; } + /** - * Display additional text from NewGRF in the purchase information window - * @param left Left border of text bounding box - * @param right Right border of text bounding box - * @param y Top border of text bounding box - * @param engine Engine to query the additional purchase information for - * @return Bottom border of text bounding box + * Try to get the NewGRF engine additional text callback as an optional std::string. + * @param engine The engine whose additional text to get. + * @return The std::string if present, otherwise std::nullopt. */ -static uint ShowAdditionalText(int left, int right, int y, EngineID engine) +static std::optional GetNewGRFAdditionalText(EngineID engine) { uint16 callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, nullptr); - if (callback == CALLBACK_FAILED || callback == 0x400) return y; + if (callback == CALLBACK_FAILED || callback == 0x400) return std::nullopt; const GRFFile *grffile = Engine::Get(engine)->GetGRF(); assert(grffile != nullptr); if (callback > 0x400) { ErrorUnknownCallbackResult(grffile->grfid, CBID_VEHICLE_ADDITIONAL_TEXT, callback); - return y; + return std::nullopt; } StartTextRefStackUsage(grffile, 6); - uint result = DrawStringMultiLine(left, right, y, INT32_MAX, GetGRFStringID(grffile->grfid, 0xD000 + callback), TC_BLACK); + std::string result = GetString(GetGRFStringID(grffile->grfid, 0xD000 + callback)); StopTextRefStackUsage(); return result; } +/** + * Display additional text from NewGRF in the purchase information window + * @param left Left border of text bounding box + * @param right Right border of text bounding box + * @param y Top border of text bounding box + * @param engine Engine to query the additional purchase information for + * @return Bottom border of text bounding box + */ +static uint ShowAdditionalText(int left, int right, int y, EngineID engine) +{ + auto text = GetNewGRFAdditionalText(engine); + if (!text) return y; + return DrawStringMultiLine(left, right, y, INT32_MAX, *text, TC_BLACK); +} + void TestedEngineDetails::FillDefaultCapacities(const Engine *e) { this->cargo = e->GetDefaultCargoType(); @@ -1091,6 +1108,11 @@ void DisplayVehicleSortDropDown(Window *w, VehicleType vehicle_type, int selecte ShowDropDownMenu(w, _engine_sort_listing[vehicle_type], selected, button, 0, hidden_mask); } +/** Enum referring to the Hotkeys in the build vehicle window */ +enum BuildVehicleHotkeys { + BVHK_FOCUS_FILTER_BOX, ///< Focus the edit box for editing the filter string +}; + /** GUI for building vehicles. */ struct BuildVehicleWindow : Window { VehicleType vehicle_type; ///< Type of vehicles shown in the window. @@ -1112,6 +1134,9 @@ struct BuildVehicleWindow : Window { Scrollbar *vscroll; TestedEngineDetails te; ///< Tested cost and capacity after refit. + StringFilter string_filter; ///< Filter for vehicle name + QueryString vehicle_editbox; ///< Filter editbox + void SetBuyVehicleText() { NWidgetCore *widget = this->GetWidget(WID_BV_BUILD); @@ -1149,7 +1174,7 @@ struct BuildVehicleWindow : Window { } } - BuildVehicleWindow(WindowDesc *desc, TileIndex tile, VehicleType type) : Window(desc) + BuildVehicleWindow(WindowDesc *desc, TileIndex tile, VehicleType type) : Window(desc), vehicle_editbox(MAX_LENGTH_VEHICLE_NAME_CHARS * MAX_CHAR_LENGTH, MAX_LENGTH_VEHICLE_NAME_CHARS) { this->vehicle_type = type; this->listview_mode = tile == INVALID_TILE; @@ -1190,6 +1215,9 @@ struct BuildVehicleWindow : Window { this->FinishInitNested(tile == INVALID_TILE ? (int)type : (int)tile); + this->querystrings[WID_BV_FILTER] = &this->vehicle_editbox; + this->vehicle_editbox.cancel_button = QueryString::ACTION_CLEAR; + this->owner = (tile != INVALID_TILE) ? GetTileOwner(tile) : _local_company; this->eng_list.ForceRebuild(); @@ -1335,6 +1363,23 @@ struct BuildVehicleWindow : Window { return CargoAndEngineFilter(&item, filter_type); } + /** Filter by name and NewGRF extra text */ + bool FilterByText(const Engine *e) + { + /* Do not filter if the filter text box is empty */ + if (this->string_filter.IsEmpty()) return true; + + /* Filter engine name */ + this->string_filter.ResetState(); + this->string_filter.AddLine(GetString(e->info.string_id)); + + /* Filter NewGRF extra text */ + auto text = GetNewGRFAdditionalText(e->index); + if (text) this->string_filter.AddLine(*text); + + return this->string_filter.GetState(); + } + /* Figure out what train EngineIDs to put in the list */ void GenerateBuildTrainList(GUIEngineList &list) { @@ -1359,6 +1404,9 @@ struct BuildVehicleWindow : Window { /* Filter now! So num_engines and num_wagons is valid */ if (!FilterSingleEngine(eid)) continue; + /* Filter by name or NewGRF extra text */ + if (!FilterByText(e)) continue; + list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); if (rvi->railveh_type != RAILVEH_WAGON) num_engines++; @@ -1405,6 +1453,9 @@ struct BuildVehicleWindow : Window { if (!IsEngineBuildable(eid, VEH_ROAD, _local_company)) continue; if (this->filter.roadtype != INVALID_ROADTYPE && !HasPowerOnRoad(e->u.road.roadtype, this->filter.roadtype)) continue; + /* Filter by name or NewGRF extra text */ + if (!FilterByText(e)) continue; + this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); if (eid == this->sel_engine) sel_id = eid; @@ -1422,6 +1473,10 @@ struct BuildVehicleWindow : Window { if (!this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue; EngineID eid = e->index; if (!IsEngineBuildable(eid, VEH_SHIP, _local_company)) continue; + + /* Filter by name or NewGRF extra text */ + if (!FilterByText(e)) continue; + this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); if (eid == this->sel_engine) sel_id = eid; @@ -1449,7 +1504,11 @@ struct BuildVehicleWindow : Window { /* First VEH_END window_numbers are fake to allow a window open for all different types at once */ if (!this->listview_mode && !CanVehicleUseStation(eid, st)) continue; + /* Filter by name or NewGRF extra text */ + if (!FilterByText(e)) continue; + this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); + if (eid == this->sel_engine) sel_id = eid; } @@ -1790,13 +1849,45 @@ struct BuildVehicleWindow : Window { { this->vscroll->SetCapacityFromWidget(this, WID_BV_LIST); } + + void OnEditboxChanged(int wid) override + { + if (wid == WID_BV_FILTER) { + this->string_filter.SetFilterTerm(this->vehicle_editbox.text.buf); + this->InvalidateData(); + } + } + + EventState OnHotkey(int hotkey) override + { + switch (hotkey) { + case BVHK_FOCUS_FILTER_BOX: + this->SetFocusedWidget(WID_BV_FILTER); + SetFocusedWindow(this); // The user has asked to give focus to the text box, so make sure this window is focused. + return ES_HANDLED; + + default: + return ES_NOT_HANDLED; + } + + return ES_HANDLED; + } + + static HotkeyList hotkeys; +}; + +static Hotkey buildvehicle_hotkeys[] = { + Hotkey('F', "focus_filter_box", BVHK_FOCUS_FILTER_BOX), + HOTKEY_LIST_END }; +HotkeyList BuildVehicleWindow::hotkeys("buildvehicle", buildvehicle_hotkeys); static WindowDesc _build_vehicle_desc( WDP_AUTO, "build_vehicle", 240, 268, WC_BUILD_VEHICLE, WC_NONE, WDF_CONSTRUCTION, - _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets) + _nested_build_vehicle_widgets, lengthof(_nested_build_vehicle_widgets), + &BuildVehicleWindow::hotkeys ); void ShowBuildVehicleWindow(TileIndex tile, VehicleType type) diff --git a/src/widgets/build_vehicle_widget.h b/src/widgets/build_vehicle_widget.h index 861c01f680..d0374a83d3 100644 --- a/src/widgets/build_vehicle_widget.h +++ b/src/widgets/build_vehicle_widget.h @@ -16,6 +16,7 @@ enum BuildVehicleWidgets { WID_BV_SORT_ASCENDING_DESCENDING, ///< Sort direction. WID_BV_SORT_DROPDOWN, ///< Criteria of sorting dropdown. WID_BV_CARGO_FILTER_DROPDOWN, ///< Cargo filter dropdown. + WID_BV_FILTER, ///< Filter by name. WID_BV_SHOW_HIDDEN_ENGINES, ///< Toggle whether to display the hidden vehicles. WID_BV_LIST, ///< List of vehicles. WID_BV_SCROLLBAR, ///< Scrollbar of list. From 4cceaae8dcd8fbed871e18e2c281150cfcb0deaa Mon Sep 17 00:00:00 2001 From: translators Date: Mon, 1 May 2023 18:39:20 +0000 Subject: [PATCH 02/34] Update: Translations from eints --- src/lang/afrikaans.txt | 4 ++++ src/lang/arabic_egypt.txt | 4 ++++ src/lang/basque.txt | 4 ++++ src/lang/belarusian.txt | 4 ++++ src/lang/brazilian_portuguese.txt | 4 ++++ src/lang/bulgarian.txt | 4 ++++ src/lang/catalan.txt | 4 ++++ src/lang/chuvash.txt | 4 ++++ src/lang/croatian.txt | 4 ++++ src/lang/czech.txt | 4 ++++ src/lang/danish.txt | 4 ++++ src/lang/dutch.txt | 4 ++++ src/lang/english_AU.txt | 4 ++++ src/lang/english_US.txt | 4 ++++ src/lang/esperanto.txt | 4 ++++ src/lang/estonian.txt | 4 ++++ src/lang/faroese.txt | 4 ++++ src/lang/finnish.txt | 4 ++++ src/lang/french.txt | 4 ++++ src/lang/frisian.txt | 4 ++++ src/lang/gaelic.txt | 4 ++++ src/lang/galician.txt | 4 ++++ src/lang/german.txt | 4 ++++ src/lang/greek.txt | 4 ++++ src/lang/hebrew.txt | 4 ++++ src/lang/hindi.txt | 4 ++++ src/lang/hungarian.txt | 4 ++++ src/lang/icelandic.txt | 4 ++++ src/lang/ido.txt | 4 ++++ src/lang/indonesian.txt | 4 ++++ src/lang/irish.txt | 4 ++++ src/lang/italian.txt | 4 ++++ src/lang/japanese.txt | 4 ++++ src/lang/korean.txt | 4 ++++ src/lang/latin.txt | 4 ++++ src/lang/latvian.txt | 4 ++++ src/lang/lithuanian.txt | 4 ++++ src/lang/luxembourgish.txt | 4 ++++ src/lang/macedonian.txt | 4 ++++ src/lang/malay.txt | 4 ++++ src/lang/maltese.txt | 4 ++++ src/lang/marathi.txt | 4 ++++ src/lang/norwegian_bokmal.txt | 4 ++++ src/lang/norwegian_nynorsk.txt | 4 ++++ src/lang/persian.txt | 4 ++++ src/lang/polish.txt | 4 ++++ src/lang/portuguese.txt | 4 ++++ src/lang/romanian.txt | 4 ++++ src/lang/russian.txt | 4 ++++ src/lang/serbian.txt | 4 ++++ src/lang/simplified_chinese.txt | 4 ++++ src/lang/slovak.txt | 4 ++++ src/lang/slovenian.txt | 4 ++++ src/lang/spanish.txt | 4 ++++ src/lang/spanish_MX.txt | 4 ++++ src/lang/swedish.txt | 4 ++++ src/lang/tamil.txt | 4 ++++ src/lang/thai.txt | 4 ++++ src/lang/traditional_chinese.txt | 4 ++++ src/lang/turkish.txt | 4 ++++ src/lang/ukrainian.txt | 4 ++++ src/lang/urdu.txt | 4 ++++ src/lang/vietnamese.txt | 4 ++++ src/lang/welsh.txt | 4 ++++ 64 files changed, 256 insertions(+) diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index 42282eadd1..5d2232e889 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -901,6 +901,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Plak die # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spel Opsies + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Geldeenheid STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Geld eendheid keuse diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 67d935c537..040f72595c 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -895,6 +895,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}لصق # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}إعدادات اللعبه + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}وحدة العملة STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}اختيار وحدة العملة diff --git a/src/lang/basque.txt b/src/lang/basque.txt index e32b0e7fce..a84f2427c1 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -877,6 +877,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Leiho ho # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Jokoaren Aukerak + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Diru unitateak STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Diru unitatearen aukeraketa diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 13c87bba55..e953011f70 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -1210,6 +1210,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Пера # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Наладкі гульні + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Валюта STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Выбар валюты diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index c22603ab11..71feb7ce7c 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -931,6 +931,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Colar a # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opções do Jogo + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Unidades monetárias STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Seleção de unidades monetárias diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 6d3d6c50ce..8d43316c4a 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -883,6 +883,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Прем # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Настройки + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Парична единица STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Избор на парична единица diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index aa0750bed2..e6c0dfdc16 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -931,6 +931,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia el # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcions de la partida + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Moneda STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selecció de la unitat monetària diff --git a/src/lang/chuvash.txt b/src/lang/chuvash.txt index acf95424bc..09c6d2a796 100644 --- a/src/lang/chuvash.txt +++ b/src/lang/chuvash.txt @@ -482,6 +482,10 @@ STR_NEWS_MESSAGE_CAPTION :{WHITE}Пӗлт # Game options window + + + + ###length 42 STR_GAME_OPTIONS_CURRENCY_RUR :Вырӑсла тенкӗ (RUR) diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index f2f2cf5c58..461edb6a7a 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -1000,6 +1000,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopiraj # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Postavke igre + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Novčane jedinice STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Izbor novčanih jedinica diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 86fa247924..1dff393941 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -1016,6 +1016,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Nastavit # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Možnosti hry + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Měna STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Výběr jednotek měny diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 7e2aac1fd7..f530028978 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -930,6 +930,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Bevæg h # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opsætning + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valutaenhed STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Valg af valutaenhed diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index f3e52f3cb9..9fd7d3837f 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -930,6 +930,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopieer # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spelopties + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valuta STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Valuta kiezen diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index dd147d2ab0..dee9ad8a88 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -930,6 +930,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Paste th # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Game Options + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Currency units STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Currency units selection diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 48123801dd..9c6992417f 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -930,6 +930,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copy the # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Game Options + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Currency units STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Currency units selection diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index 5a284c49f5..675a1235b1 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -872,6 +872,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Gluu la # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Ludaj Opcioj + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Monunuoj STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Elekto de monunuoj diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index 0299e28714..aff88f9252 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -986,6 +986,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Vaateala # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Liidese seadistus + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valuuta STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Valuuta valimine diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 726d8d812f..bce313116a 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -857,6 +857,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Set sta # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spæli møguleikar + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Gjaldsoyra eindir STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Úrval av gjaldsoyra eindum diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index ef553f9e4b..bc5ace71c4 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -930,6 +930,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Siirrä # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Pelin valinnat + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Rahayksikkö STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Rahayksikön valinta diff --git a/src/lang/french.txt b/src/lang/french.txt index 57ac5edec8..dad4f8758b 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -931,6 +931,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copier l # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Options du jeu + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Devise STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Sélectionner l'unité monétaire diff --git a/src/lang/frisian.txt b/src/lang/frisian.txt index 23706d2e54..c60d154388 100644 --- a/src/lang/frisian.txt +++ b/src/lang/frisian.txt @@ -894,6 +894,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Plak de # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spulopsjes + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Muntienheid STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Muntienheidseleksje diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index 963c69ad08..926e2248e1 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -1090,6 +1090,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Cuir let # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Roghainnean a' gheama + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Aonadan airgeadra STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Tagh aonadan airgeadra diff --git a/src/lang/galician.txt b/src/lang/galician.txt index 5c7a5f0a1e..1e18925e50 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -931,6 +931,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia a # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcións da partida + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Unidades monetarias STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selección de unidades monetarias diff --git a/src/lang/german.txt b/src/lang/german.txt index e6d0071880..eeed9c4f32 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -930,6 +930,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Hauptans # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spieleinstellungen + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Währung STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Währung auswählen diff --git a/src/lang/greek.txt b/src/lang/greek.txt index b72104fbf4..20548625f3 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -1035,6 +1035,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Επικ # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Επιλογές Παιχνιδιού + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Νομισματικές μονάδες STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Επιλογή νομισματικών μονάδων diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index 59f8c1622d..6f1b670dc8 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -906,6 +906,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}העתק # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}אפשרויות משחק + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}מטבע STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}בחירת מטבע diff --git a/src/lang/hindi.txt b/src/lang/hindi.txt index 0643f16469..2edf8eac4f 100644 --- a/src/lang/hindi.txt +++ b/src/lang/hindi.txt @@ -270,6 +270,10 @@ STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLAC # Game options window + + + + ###length 42 STR_GAME_OPTIONS_CURRENCY_FIM :फिनलैंड मार्का (FIM) STR_GAME_OPTIONS_CURRENCY_ISK :आइसलैंडिक क्रोना (ISK) diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 79b9903483..cd4c784450 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -993,6 +993,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}A látk # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Alapbeállítások + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Pénznem STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}A használt pénznem kiválasztása diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index ab74e48c2a..dea7721b0a 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -856,6 +856,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Afrita s # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Stillingar + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Gjaldmiðill STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Val á gjaldmiðli diff --git a/src/lang/ido.txt b/src/lang/ido.txt index e3aecc8545..990c36b804 100644 --- a/src/lang/ido.txt +++ b/src/lang/ido.txt @@ -471,6 +471,10 @@ STR_NEWS_MESSAGE_CAPTION :{WHITE}Sendajo # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Ludo Selekti + + + + ###length 42 diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index 00b0db5c74..adc126cdaa 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -929,6 +929,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Perlihat # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opsi permainan + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Mata uang STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Pilih mata uang diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 36ea90ecad..2481f97817 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -918,6 +918,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Gramaigh # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Roghanna Cluiche + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Aonaid airgeadra STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Aonaid airgeadra a roghnú diff --git a/src/lang/italian.txt b/src/lang/italian.txt index be4f6f1f17..30784f4705 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -932,6 +932,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia la # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opzioni di gioco + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valuta STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selezione della valuta diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index a7f04e7f0a..ea444f0a7f 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -929,6 +929,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}この # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}ゲーム設定 + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}通貨単位 STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}通貨単位の選択 diff --git a/src/lang/korean.txt b/src/lang/korean.txt index de13e6da6b..597659cc83 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -931,6 +931,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}외부 # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}게임 기본 설정 + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}화폐 단위 STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}화폐 단위 선택 diff --git a/src/lang/latin.txt b/src/lang/latin.txt index ad799ca250..2beef7f1c0 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -1081,6 +1081,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Transcri # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Ludi optiones + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Unitates nummi STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Electio unitatum nummi diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 8f1051824a..30cf936de2 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -931,6 +931,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopēt # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spēles opcijas + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Naudas vienības STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Naudas vienību izvēle diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index eadc43a877..26d135c9ec 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -1129,6 +1129,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Įkelti # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Pagrindinės nuostatos + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valiuta STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Valiutos pasirinkimas diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 32f3bd201b..8c85afe85c 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -929,6 +929,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Setzt d' # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spill Optiounen + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Währungseenheet STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Währungseenheet wielen diff --git a/src/lang/macedonian.txt b/src/lang/macedonian.txt index 1b2a4b0dd5..bf0efa52d4 100644 --- a/src/lang/macedonian.txt +++ b/src/lang/macedonian.txt @@ -790,6 +790,10 @@ STR_NEWS_AIRCRAFT_DEST_TOO_FAR :{WHITE}{VEHICLE # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Опции на Играта + + + + ###length 42 diff --git a/src/lang/malay.txt b/src/lang/malay.txt index 0e39213214..b7e5433b31 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -861,6 +861,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Salin lo # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Pilihan Permainan + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Unit kewangan STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Pilihan unit kewangan diff --git a/src/lang/maltese.txt b/src/lang/maltese.txt index c3afc0c70c..0dacd67a81 100644 --- a/src/lang/maltese.txt +++ b/src/lang/maltese.txt @@ -404,6 +404,10 @@ STR_NEWS_VEHICLE_IS_LOST :{WHITE}{VEHICLE # Game options window + + + + ###length 42 diff --git a/src/lang/marathi.txt b/src/lang/marathi.txt index f4ce363e64..99d362f958 100644 --- a/src/lang/marathi.txt +++ b/src/lang/marathi.txt @@ -697,6 +697,10 @@ STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLAC # Game options window + + + + ###length 42 STR_GAME_OPTIONS_CURRENCY_GBP :पौंड (£) STR_GAME_OPTIONS_CURRENCY_USD :डोल्लर ($) diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index e70a645baa..a5db6c1e1b 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -922,6 +922,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}flytt pl # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spillinnstillinger + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valutaenhet STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Velg valutaenhet som skal brukes diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index b8c185d792..306b8cae03 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -887,6 +887,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopier s # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spelinnstillingar + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valutaeining STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Vel valutaeining diff --git a/src/lang/persian.txt b/src/lang/persian.txt index 6e4d28d63d..96830e2a1c 100644 --- a/src/lang/persian.txt +++ b/src/lang/persian.txt @@ -877,6 +877,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}موقع # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}تنظیمات بازی + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}واحد پول STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}انتخب واحد پول diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 520656080e..2de45246ad 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -1310,6 +1310,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopiuj p # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcje gry + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Waluta STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Wybór waluty diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 788e60d54d..de27d357fd 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -931,6 +931,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copiar a # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opções do Jogo + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Unidades monetárias STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selecção de unidades monetárias diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index af0acccaff..5937dc2a2d 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -929,6 +929,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copiază # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opţiuni + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Unitate monetară STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Alege unitatea monetară diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 8254fd0f4f..cdbbb10659 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -1075,6 +1075,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Пока # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Основные настройки + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Валюта STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Смена используемой в игре валюты diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index 39565c8ac6..48284c5029 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -1124,6 +1124,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopiraj # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcije + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valuta STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Izbor valute diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 4aa10b4f22..dab40d810d 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -929,6 +929,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}将主 # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}游戏选项 + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}货币单位 STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}货币单位选择 diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 03b4125aa9..3017735ebf 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -998,6 +998,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Nastavi # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Možnosti hry + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Mena STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Výber menovej jednotky diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index 9a9e1954fa..50ca2ecf32 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -1041,6 +1041,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Prilepi # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Možnosti Igre + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valute STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Izbira valut diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index e8f04ac022..8ae6ed6f05 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -930,6 +930,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia la # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opciones del juego + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Unidad monetaria STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selecciona la nnidad monetaria diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index ecc22dc1dd..f8e079e636 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -930,6 +930,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copiar u # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opciones de juego + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Divisa STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Elegir divisa diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 1ad90a5727..11d759b92f 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -929,6 +929,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopiera # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Spelinställningar + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valutaenheter STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Välj valutaenhet diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index 899cdb826d..28bf1d7b66 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -889,6 +889,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}பி # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}ஆட்டத்தின் அமைப்புகள் + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}நாணய பிரிவுகள் STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}நாணய பிரிவு தேர்ந்தெடுத்தல் diff --git a/src/lang/thai.txt b/src/lang/thai.txt index 3082cdc9db..8cb07fdf77 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -900,6 +900,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}วา # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}ตัวเลือกเกม + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}หน่วยสกุลเงิน STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}การเลือกสกุลเงิน diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 747f5c6ff0..d71cea6b86 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -929,6 +929,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}將主 # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}遊戲選項 + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}幣值單位 STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}選擇幣值單位 diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index dd1c56f04b..e2f5680b30 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -931,6 +931,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Bu gör # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Seçenekler + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Para birimleri STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Para birimi seçimi diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index 06d65ecea9..7488fdd2e7 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -1057,6 +1057,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Пере # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Налаштування гри + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Грошова одиниця STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Виберіть грошову одиницю diff --git a/src/lang/urdu.txt b/src/lang/urdu.txt index 7e0c993ea4..12bdf58589 100644 --- a/src/lang/urdu.txt +++ b/src/lang/urdu.txt @@ -854,6 +854,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}دیکھ # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}کھیل کے اختیارات + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}کرنسی کی اکائیاں STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}کرنسی کی اکائی اختیار کریں diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index ad22d47759..f7df733a98 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -930,6 +930,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Sao ché # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Cấu Hình Trò Chơi + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Đơn vị tiền tệ STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Lựa chọn đơn vị tiền tệ diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 1404de439f..9df1ddf322 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -887,6 +887,10 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Gludo ll # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Dewisiadau Gêm + + + + STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Uned Arian STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Dewis unedau arian From 9cb60768fed118339b6cebfbaf3ca2c1461eb774 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Mon, 1 May 2023 14:42:51 +0200 Subject: [PATCH 03/34] Codechange: split implementations of ParagraphLayouterFactory into their own file --- src/CMakeLists.txt | 8 + src/gfx_layout.cpp | 551 +----------------------------------- src/gfx_layout_fallback.cpp | 376 ++++++++++++++++++++++++ src/gfx_layout_fallback.h | 30 ++ src/gfx_layout_icu.cpp | 181 ++++++++++++ src/gfx_layout_icu.h | 30 ++ 6 files changed, 628 insertions(+), 548 deletions(-) create mode 100644 src/gfx_layout_fallback.cpp create mode 100644 src/gfx_layout_fallback.h create mode 100644 src/gfx_layout_icu.cpp create mode 100644 src/gfx_layout_icu.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6bd62e4224..ce078a02af 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,6 +33,12 @@ add_files( CONDITION SSE_FOUND ) +add_files( + gfx_layout_icu.cpp + gfx_layout_icu.h + CONDITION ICU_lx_FOUND +) + add_files( aircraft.h aircraft_cmd.cpp @@ -175,6 +181,8 @@ add_files( gfx_func.h gfx_layout.cpp gfx_layout.h + gfx_layout_fallback.cpp + gfx_layout_fallback.h gfx_type.h gfxinit.cpp gfxinit.h diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index 1a163330d2..ab40b55737 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -16,8 +16,10 @@ #include "table/control_codes.h" +#include "gfx_layout_fallback.h" + #ifdef WITH_ICU_LX -#include +#include "gfx_layout_icu.h" #endif /* WITH_ICU_LX */ #ifdef WITH_UNISCRIBE @@ -49,553 +51,6 @@ Font::Font(FontSize size, TextColour colour) : assert(size < FS_END); } -#ifdef WITH_ICU_LX -/* Implementation details of LEFontInstance */ - -le_int32 Font::getUnitsPerEM() const -{ - return this->fc->GetUnitsPerEM(); -} - -le_int32 Font::getAscent() const -{ - return this->fc->GetAscender(); -} - -le_int32 Font::getDescent() const -{ - return -this->fc->GetDescender(); -} - -le_int32 Font::getLeading() const -{ - return this->fc->GetHeight(); -} - -float Font::getXPixelsPerEm() const -{ - return (float)this->fc->GetHeight(); -} - -float Font::getYPixelsPerEm() const -{ - return (float)this->fc->GetHeight(); -} - -float Font::getScaleFactorX() const -{ - return 1.0f; -} - -float Font::getScaleFactorY() const -{ - return 1.0f; -} - -const void *Font::getFontTable(LETag tableTag) const -{ - size_t length; - return this->getFontTable(tableTag, length); -} - -const void *Font::getFontTable(LETag tableTag, size_t &length) const -{ - return this->fc->GetFontTable(tableTag, length); -} - -LEGlyphID Font::mapCharToGlyph(LEUnicode32 ch) const -{ - if (IsTextDirectionChar(ch)) return 0; - return this->fc->MapCharToGlyph(ch); -} - -void Font::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const -{ - advance.fX = glyph == 0xFFFF ? 0 : this->fc->GetGlyphWidth(glyph); - advance.fY = 0; -} - -le_bool Font::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const -{ - return false; -} - -/** - * Wrapper for doing layouts with ICU. - */ -class ICUParagraphLayout : public ParagraphLayouter { - icu::ParagraphLayout *p; ///< The actual ICU paragraph layout. -public: - /** Visual run contains data about the bit of text with the same font. */ - class ICUVisualRun : public ParagraphLayouter::VisualRun { - const icu::ParagraphLayout::VisualRun *vr; ///< The actual ICU vr. - - public: - ICUVisualRun(const icu::ParagraphLayout::VisualRun *vr) : vr(vr) { } - - const Font *GetFont() const override { return (const Font*)vr->getFont(); } - int GetGlyphCount() const override { return vr->getGlyphCount(); } - const GlyphID *GetGlyphs() const override { return vr->getGlyphs(); } - const float *GetPositions() const override { return vr->getPositions(); } - int GetLeading() const override { return vr->getLeading(); } - const int *GetGlyphToCharMap() const override { return vr->getGlyphToCharMap(); } - }; - - /** A single line worth of VisualRuns. */ - class ICULine : public std::vector, public ParagraphLayouter::Line { - icu::ParagraphLayout::Line *l; ///< The actual ICU line. - - public: - ICULine(icu::ParagraphLayout::Line *l) : l(l) - { - for (int i = 0; i < l->countRuns(); i++) { - this->emplace_back(l->getVisualRun(i)); - } - } - ~ICULine() override { delete l; } - - int GetLeading() const override { return l->getLeading(); } - int GetWidth() const override { return l->getWidth(); } - int CountRuns() const override { return l->countRuns(); } - const ParagraphLayouter::VisualRun &GetVisualRun(int run) const override { return this->at(run); } - - int GetInternalCharLength(WChar c) const override - { - /* ICU uses UTF-16 internally which means we need to account for surrogate pairs. */ - return Utf8CharLen(c) < 4 ? 1 : 2; - } - }; - - ICUParagraphLayout(icu::ParagraphLayout *p) : p(p) { } - ~ICUParagraphLayout() override { delete p; } - void Reflow() override { p->reflow(); } - - std::unique_ptr NextLine(int max_width) override - { - icu::ParagraphLayout::Line *l = p->nextLine(max_width); - return std::unique_ptr(l == nullptr ? nullptr : new ICULine(l)); - } -}; - -/** - * Helper class to construct a new #ICUParagraphLayout. - */ -class ICUParagraphLayoutFactory { -public: - /** Helper for GetLayouter, to get the right type. */ - typedef UChar CharType; - /** Helper for GetLayouter, to get whether the layouter supports RTL. */ - static const bool SUPPORTS_RTL = true; - - static ParagraphLayouter *GetParagraphLayout(UChar *buff, UChar *buff_end, FontMap &fontMapping) - { - int32 length = buff_end - buff; - - if (length == 0) { - /* ICU's ParagraphLayout cannot handle empty strings, so fake one. */ - buff[0] = ' '; - length = 1; - fontMapping.back().first++; - } - - /* Fill ICU's FontRuns with the right data. */ - icu::FontRuns runs(fontMapping.size()); - for (auto &pair : fontMapping) { - runs.add(pair.second, pair.first); - } - - LEErrorCode status = LE_NO_ERROR; - /* ParagraphLayout does not copy "buff", so it must stay valid. - * "runs" is copied according to the ICU source, but the documentation does not specify anything, so this might break somewhen. */ - icu::ParagraphLayout *p = new icu::ParagraphLayout(buff, length, &runs, nullptr, nullptr, nullptr, _current_text_dir == TD_RTL ? 1 : 0, false, status); - if (status != LE_NO_ERROR) { - delete p; - return nullptr; - } - - return new ICUParagraphLayout(p); - } - - static size_t AppendToBuffer(UChar *buff, const UChar *buffer_last, WChar c) - { - /* Transform from UTF-32 to internal ICU format of UTF-16. */ - int32 length = 0; - UErrorCode err = U_ZERO_ERROR; - u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err); - return length; - } -}; -#endif /* WITH_ICU_LX */ - -/*** Paragraph layout ***/ -/** - * Class handling the splitting of a paragraph of text into lines and - * visual runs. - * - * One constructs this class with the text that needs to be split into - * lines. Then nextLine is called with the maximum width until nullptr is - * returned. Each nextLine call creates VisualRuns which contain the - * length of text that are to be drawn with the same font. In other - * words, the result of this class is a list of sub strings with their - * font. The sub strings are then already fully laid out, and only - * need actual drawing. - * - * The positions in a visual run are sequential pairs of X,Y of the - * begin of each of the glyphs plus an extra pair to mark the end. - * - * @note This variant does not handle left-to-right properly. This - * is supported in the one ParagraphLayout coming from ICU. - */ -class FallbackParagraphLayout : public ParagraphLayouter { -public: - /** Visual run contains data about the bit of text with the same font. */ - class FallbackVisualRun : public ParagraphLayouter::VisualRun { - Font *font; ///< The font used to layout these. - GlyphID *glyphs; ///< The glyphs we're drawing. - float *positions; ///< The positions of the glyphs. - int *glyph_to_char; ///< The char index of the glyphs. - int glyph_count; ///< The number of glyphs. - - public: - FallbackVisualRun(Font *font, const WChar *chars, int glyph_count, int x); - FallbackVisualRun(FallbackVisualRun &&other) noexcept; - ~FallbackVisualRun() override; - const Font *GetFont() const override; - int GetGlyphCount() const override; - const GlyphID *GetGlyphs() const override; - const float *GetPositions() const override; - int GetLeading() const override; - const int *GetGlyphToCharMap() const override; - }; - - /** A single line worth of VisualRuns. */ - class FallbackLine : public std::vector, public ParagraphLayouter::Line { - public: - int GetLeading() const override; - int GetWidth() const override; - int CountRuns() const override; - const ParagraphLayouter::VisualRun &GetVisualRun(int run) const override; - - int GetInternalCharLength(WChar c) const override { return 1; } - }; - - const WChar *buffer_begin; ///< Begin of the buffer. - const WChar *buffer; ///< The current location in the buffer. - FontMap &runs; ///< The fonts we have to use for this paragraph. - - FallbackParagraphLayout(WChar *buffer, int length, FontMap &runs); - void Reflow() override; - std::unique_ptr NextLine(int max_width) override; -}; - -/** - * Helper class to construct a new #FallbackParagraphLayout. - */ -class FallbackParagraphLayoutFactory { -public: - /** Helper for GetLayouter, to get the right type. */ - typedef WChar CharType; - /** Helper for GetLayouter, to get whether the layouter supports RTL. */ - static const bool SUPPORTS_RTL = false; - - /** - * Get the actual ParagraphLayout for the given buffer. - * @param buff The begin of the buffer. - * @param buff_end The location after the last element in the buffer. - * @param fontMapping THe mapping of the fonts. - * @return The ParagraphLayout instance. - */ - static ParagraphLayouter *GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping) - { - return new FallbackParagraphLayout(buff, buff_end - buff, fontMapping); - } - - /** - * Append a wide character to the internal buffer. - * @param buff The buffer to append to. - * @param buffer_last The end of the buffer. - * @param c The character to add. - * @return The number of buffer spaces that were used. - */ - static size_t AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c) - { - *buff = c; - return 1; - } -}; - -/** - * Create the visual run. - * @param font The font to use for this run. - * @param chars The characters to use for this run. - * @param char_count The number of characters in this run. - * @param x The initial x position for this run. - */ -FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const WChar *chars, int char_count, int x) : - font(font), glyph_count(char_count) -{ - const bool isbuiltin = font->fc->IsBuiltInFont(); - - this->glyphs = MallocT(this->glyph_count); - this->glyph_to_char = MallocT(this->glyph_count); - - /* Positions contains the location of the begin of each of the glyphs, and the end of the last one. */ - this->positions = MallocT(this->glyph_count * 2 + 2); - this->positions[0] = x; - - for (int i = 0; i < this->glyph_count; i++) { - this->glyphs[i] = font->fc->MapCharToGlyph(chars[i]); - if (isbuiltin) { - this->positions[2 * i + 1] = font->fc->GetAscender(); // Apply sprite font's ascender. - } else if (chars[i] >= SCC_SPRITE_START && chars[i] <= SCC_SPRITE_END) { - this->positions[2 * i + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre - } else { - this->positions[2 * i + 1] = 0; // No ascender adjustment. - } - this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(this->glyphs[i]); - this->glyph_to_char[i] = i; - } -} - -/** Move constructor for visual runs.*/ -FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(FallbackVisualRun &&other) noexcept : font(other.font), glyph_count(other.glyph_count) -{ - this->positions = other.positions; - this->glyph_to_char = other.glyph_to_char; - this->glyphs = other.glyphs; - - other.positions = nullptr; - other.glyph_to_char = nullptr; - other.glyphs = nullptr; -} - -/** Free all data. */ -FallbackParagraphLayout::FallbackVisualRun::~FallbackVisualRun() -{ - free(this->positions); - free(this->glyph_to_char); - free(this->glyphs); -} - -/** - * Get the font associated with this run. - * @return The font. - */ -const Font *FallbackParagraphLayout::FallbackVisualRun::GetFont() const -{ - return this->font; -} - -/** - * Get the number of glyphs in this run. - * @return The number of glyphs. - */ -int FallbackParagraphLayout::FallbackVisualRun::GetGlyphCount() const -{ - return this->glyph_count; -} - -/** - * Get the glyphs of this run. - * @return The glyphs. - */ -const GlyphID *FallbackParagraphLayout::FallbackVisualRun::GetGlyphs() const -{ - return this->glyphs; -} - -/** - * Get the positions of this run. - * @return The positions. - */ -const float *FallbackParagraphLayout::FallbackVisualRun::GetPositions() const -{ - return this->positions; -} - -/** - * Get the glyph-to-character map for this visual run. - * @return The glyph-to-character map. - */ -const int *FallbackParagraphLayout::FallbackVisualRun::GetGlyphToCharMap() const -{ - return this->glyph_to_char; -} - -/** - * Get the height of this font. - * @return The height of the font. - */ -int FallbackParagraphLayout::FallbackVisualRun::GetLeading() const -{ - return this->GetFont()->fc->GetHeight(); -} - -/** - * Get the height of the line. - * @return The maximum height of the line. - */ -int FallbackParagraphLayout::FallbackLine::GetLeading() const -{ - int leading = 0; - for (const auto &run : *this) { - leading = std::max(leading, run.GetLeading()); - } - - return leading; -} - -/** - * Get the width of this line. - * @return The width of the line. - */ -int FallbackParagraphLayout::FallbackLine::GetWidth() const -{ - if (this->size() == 0) return 0; - - /* - * The last X position of a run contains is the end of that run. - * Since there is no left-to-right support, taking this value of - * the last run gives us the end of the line and thus the width. - */ - const auto &run = this->GetVisualRun(this->CountRuns() - 1); - return (int)run.GetPositions()[run.GetGlyphCount() * 2]; -} - -/** - * Get the number of runs in this line. - * @return The number of runs. - */ -int FallbackParagraphLayout::FallbackLine::CountRuns() const -{ - return (uint)this->size(); -} - -/** - * Get a specific visual run. - * @return The visual run. - */ -const ParagraphLayouter::VisualRun &FallbackParagraphLayout::FallbackLine::GetVisualRun(int run) const -{ - return this->at(run); -} - -/** - * Create a new paragraph layouter. - * @param buffer The characters of the paragraph. - * @param length The length of the paragraph. - * @param runs The font mapping of this paragraph. - */ -FallbackParagraphLayout::FallbackParagraphLayout(WChar *buffer, int length, FontMap &runs) : buffer_begin(buffer), buffer(buffer), runs(runs) -{ - assert(runs.End()[-1].first == length); -} - -/** - * Reset the position to the start of the paragraph. - */ -void FallbackParagraphLayout::Reflow() -{ - this->buffer = this->buffer_begin; -} - -/** - * Construct a new line with a maximum width. - * @param max_width The maximum width of the string. - * @return A Line, or nullptr when at the end of the paragraph. - */ -std::unique_ptr FallbackParagraphLayout::NextLine(int max_width) -{ - /* Simple idea: - * - split a line at a newline character, or at a space where we can break a line. - * - split for a visual run whenever a new line happens, or the font changes. - */ - if (this->buffer == nullptr) return nullptr; - - std::unique_ptr l(new FallbackLine()); - - if (*this->buffer == '\0') { - /* Only a newline. */ - this->buffer = nullptr; - l->emplace_back(this->runs.front().second, this->buffer, 0, 0); - return l; - } - - int offset = this->buffer - this->buffer_begin; - FontMap::iterator iter = this->runs.data(); - while (iter->first <= offset) { - iter++; - assert(iter != this->runs.End()); - } - - const FontCache *fc = iter->second->fc; - const WChar *next_run = this->buffer_begin + iter->first; - - const WChar *begin = this->buffer; - const WChar *last_space = nullptr; - const WChar *last_char; - int width = 0; - for (;;) { - WChar c = *this->buffer; - last_char = this->buffer; - - if (c == '\0') { - this->buffer = nullptr; - break; - } - - if (this->buffer == next_run) { - int w = l->GetWidth(); - l->emplace_back(iter->second, begin, this->buffer - begin, w); - iter++; - assert(iter != this->runs.End()); - - next_run = this->buffer_begin + iter->first; - begin = this->buffer; - } - - if (IsWhitespace(c)) last_space = this->buffer; - - if (IsPrintable(c) && !IsTextDirectionChar(c)) { - int char_width = GetCharacterWidth(fc->GetSize(), c); - width += char_width; - if (width > max_width) { - /* The string is longer than maximum width so we need to decide - * what to do with it. */ - if (width == char_width) { - /* The character is wider than allowed width; don't know - * what to do with this case... bail out! */ - this->buffer = nullptr; - return l; - } - - if (last_space == nullptr) { - /* No space has been found. Just terminate at our current - * location. This usually happens for languages that do not - * require spaces in strings, like Chinese, Japanese and - * Korean. For other languages terminating mid-word might - * not be the best, but terminating the whole string instead - * of continuing the word at the next line is worse. */ - last_char = this->buffer; - } else { - /* A space is found; perfect place to terminate */ - this->buffer = last_space + 1; - last_char = last_space; - } - break; - } - } - - this->buffer++; - } - - if (l->size() == 0 || last_char - begin > 0) { - int w = l->GetWidth(); - l->emplace_back(iter->second, begin, last_char - begin, w); - } - return l; -} - /** * Helper for getting a ParagraphLayouter of the given type. * diff --git a/src/gfx_layout_fallback.cpp b/src/gfx_layout_fallback.cpp new file mode 100644 index 0000000000..2274ad1637 --- /dev/null +++ b/src/gfx_layout_fallback.cpp @@ -0,0 +1,376 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file gfx_layout_fallback.cpp Handling of laying out text as fallback. */ + +#include "stdafx.h" + +#include "gfx_layout_fallback.h" +#include "string_func.h" +#include "zoom_func.h" + +#include "table/control_codes.h" + +#include "safeguards.h" + +/*** Paragraph layout ***/ +/** + * Class handling the splitting of a paragraph of text into lines and + * visual runs. + * + * One constructs this class with the text that needs to be split into + * lines. Then nextLine is called with the maximum width until nullptr is + * returned. Each nextLine call creates VisualRuns which contain the + * length of text that are to be drawn with the same font. In other + * words, the result of this class is a list of sub strings with their + * font. The sub strings are then already fully laid out, and only + * need actual drawing. + * + * The positions in a visual run are sequential pairs of X,Y of the + * begin of each of the glyphs plus an extra pair to mark the end. + * + * @note This variant does not handle left-to-right properly. This + * is supported in the one ParagraphLayout coming from ICU. + */ +class FallbackParagraphLayout : public ParagraphLayouter { +public: + /** Visual run contains data about the bit of text with the same font. */ + class FallbackVisualRun : public ParagraphLayouter::VisualRun { + Font *font; ///< The font used to layout these. + GlyphID *glyphs; ///< The glyphs we're drawing. + float *positions; ///< The positions of the glyphs. + int *glyph_to_char; ///< The char index of the glyphs. + int glyph_count; ///< The number of glyphs. + + public: + FallbackVisualRun(Font *font, const WChar *chars, int glyph_count, int x); + FallbackVisualRun(FallbackVisualRun &&other) noexcept; + ~FallbackVisualRun() override; + const Font *GetFont() const override; + int GetGlyphCount() const override; + const GlyphID *GetGlyphs() const override; + const float *GetPositions() const override; + int GetLeading() const override; + const int *GetGlyphToCharMap() const override; + }; + + /** A single line worth of VisualRuns. */ + class FallbackLine : public std::vector, public ParagraphLayouter::Line { + public: + int GetLeading() const override; + int GetWidth() const override; + int CountRuns() const override; + const ParagraphLayouter::VisualRun &GetVisualRun(int run) const override; + + int GetInternalCharLength(WChar c) const override { return 1; } + }; + + const WChar *buffer_begin; ///< Begin of the buffer. + const WChar *buffer; ///< The current location in the buffer. + FontMap &runs; ///< The fonts we have to use for this paragraph. + + FallbackParagraphLayout(WChar *buffer, int length, FontMap &runs); + void Reflow() override; + std::unique_ptr NextLine(int max_width) override; +}; + +/** + * Get the actual ParagraphLayout for the given buffer. + * @param buff The begin of the buffer. + * @param buff_end The location after the last element in the buffer. + * @param fontMapping THe mapping of the fonts. + * @return The ParagraphLayout instance. + */ +/* static */ ParagraphLayouter *FallbackParagraphLayoutFactory::GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping) +{ + return new FallbackParagraphLayout(buff, buff_end - buff, fontMapping); +} + +/** + * Append a wide character to the internal buffer. + * @param buff The buffer to append to. + * @param buffer_last The end of the buffer. + * @param c The character to add. + * @return The number of buffer spaces that were used. + */ +/* static */ size_t FallbackParagraphLayoutFactory::AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c) +{ + *buff = c; + return 1; +} + +/** + * Create the visual run. + * @param font The font to use for this run. + * @param chars The characters to use for this run. + * @param char_count The number of characters in this run. + * @param x The initial x position for this run. + */ +FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const WChar *chars, int char_count, int x) : + font(font), glyph_count(char_count) +{ + const bool isbuiltin = font->fc->IsBuiltInFont(); + + this->glyphs = MallocT(this->glyph_count); + this->glyph_to_char = MallocT(this->glyph_count); + + /* Positions contains the location of the begin of each of the glyphs, and the end of the last one. */ + this->positions = MallocT(this->glyph_count * 2 + 2); + this->positions[0] = x; + + for (int i = 0; i < this->glyph_count; i++) { + this->glyphs[i] = font->fc->MapCharToGlyph(chars[i]); + if (isbuiltin) { + this->positions[2 * i + 1] = font->fc->GetAscender(); // Apply sprite font's ascender. + } else if (chars[i] >= SCC_SPRITE_START && chars[i] <= SCC_SPRITE_END) { + this->positions[2 * i + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre + } else { + this->positions[2 * i + 1] = 0; // No ascender adjustment. + } + this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(this->glyphs[i]); + this->glyph_to_char[i] = i; + } +} + +/** Move constructor for visual runs.*/ +FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(FallbackVisualRun &&other) noexcept : font(other.font), glyph_count(other.glyph_count) +{ + this->positions = other.positions; + this->glyph_to_char = other.glyph_to_char; + this->glyphs = other.glyphs; + + other.positions = nullptr; + other.glyph_to_char = nullptr; + other.glyphs = nullptr; +} + +/** Free all data. */ +FallbackParagraphLayout::FallbackVisualRun::~FallbackVisualRun() +{ + free(this->positions); + free(this->glyph_to_char); + free(this->glyphs); +} + +/** + * Get the font associated with this run. + * @return The font. + */ +const Font *FallbackParagraphLayout::FallbackVisualRun::GetFont() const +{ + return this->font; +} + +/** + * Get the number of glyphs in this run. + * @return The number of glyphs. + */ +int FallbackParagraphLayout::FallbackVisualRun::GetGlyphCount() const +{ + return this->glyph_count; +} + +/** + * Get the glyphs of this run. + * @return The glyphs. + */ +const GlyphID *FallbackParagraphLayout::FallbackVisualRun::GetGlyphs() const +{ + return this->glyphs; +} + +/** + * Get the positions of this run. + * @return The positions. + */ +const float *FallbackParagraphLayout::FallbackVisualRun::GetPositions() const +{ + return this->positions; +} + +/** + * Get the glyph-to-character map for this visual run. + * @return The glyph-to-character map. + */ +const int *FallbackParagraphLayout::FallbackVisualRun::GetGlyphToCharMap() const +{ + return this->glyph_to_char; +} + +/** + * Get the height of this font. + * @return The height of the font. + */ +int FallbackParagraphLayout::FallbackVisualRun::GetLeading() const +{ + return this->GetFont()->fc->GetHeight(); +} + +/** + * Get the height of the line. + * @return The maximum height of the line. + */ +int FallbackParagraphLayout::FallbackLine::GetLeading() const +{ + int leading = 0; + for (const auto &run : *this) { + leading = std::max(leading, run.GetLeading()); + } + + return leading; +} + +/** + * Get the width of this line. + * @return The width of the line. + */ +int FallbackParagraphLayout::FallbackLine::GetWidth() const +{ + if (this->size() == 0) return 0; + + /* + * The last X position of a run contains is the end of that run. + * Since there is no left-to-right support, taking this value of + * the last run gives us the end of the line and thus the width. + */ + const auto &run = this->GetVisualRun(this->CountRuns() - 1); + return (int)run.GetPositions()[run.GetGlyphCount() * 2]; +} + +/** + * Get the number of runs in this line. + * @return The number of runs. + */ +int FallbackParagraphLayout::FallbackLine::CountRuns() const +{ + return (uint)this->size(); +} + +/** + * Get a specific visual run. + * @return The visual run. + */ +const ParagraphLayouter::VisualRun &FallbackParagraphLayout::FallbackLine::GetVisualRun(int run) const +{ + return this->at(run); +} + +/** + * Create a new paragraph layouter. + * @param buffer The characters of the paragraph. + * @param length The length of the paragraph. + * @param runs The font mapping of this paragraph. + */ +FallbackParagraphLayout::FallbackParagraphLayout(WChar *buffer, int length, FontMap &runs) : buffer_begin(buffer), buffer(buffer), runs(runs) +{ + assert(runs.End()[-1].first == length); +} + +/** + * Reset the position to the start of the paragraph. + */ +void FallbackParagraphLayout::Reflow() +{ + this->buffer = this->buffer_begin; +} + +/** + * Construct a new line with a maximum width. + * @param max_width The maximum width of the string. + * @return A Line, or nullptr when at the end of the paragraph. + */ +std::unique_ptr FallbackParagraphLayout::NextLine(int max_width) +{ + /* Simple idea: + * - split a line at a newline character, or at a space where we can break a line. + * - split for a visual run whenever a new line happens, or the font changes. + */ + if (this->buffer == nullptr) return nullptr; + + std::unique_ptr l(new FallbackLine()); + + if (*this->buffer == '\0') { + /* Only a newline. */ + this->buffer = nullptr; + l->emplace_back(this->runs.front().second, this->buffer, 0, 0); + return l; + } + + int offset = this->buffer - this->buffer_begin; + FontMap::iterator iter = this->runs.data(); + while (iter->first <= offset) { + iter++; + assert(iter != this->runs.End()); + } + + const FontCache *fc = iter->second->fc; + const WChar *next_run = this->buffer_begin + iter->first; + + const WChar *begin = this->buffer; + const WChar *last_space = nullptr; + const WChar *last_char; + int width = 0; + for (;;) { + WChar c = *this->buffer; + last_char = this->buffer; + + if (c == '\0') { + this->buffer = nullptr; + break; + } + + if (this->buffer == next_run) { + int w = l->GetWidth(); + l->emplace_back(iter->second, begin, this->buffer - begin, w); + iter++; + assert(iter != this->runs.End()); + + next_run = this->buffer_begin + iter->first; + begin = this->buffer; + } + + if (IsWhitespace(c)) last_space = this->buffer; + + if (IsPrintable(c) && !IsTextDirectionChar(c)) { + int char_width = GetCharacterWidth(fc->GetSize(), c); + width += char_width; + if (width > max_width) { + /* The string is longer than maximum width so we need to decide + * what to do with it. */ + if (width == char_width) { + /* The character is wider than allowed width; don't know + * what to do with this case... bail out! */ + this->buffer = nullptr; + return l; + } + + if (last_space == nullptr) { + /* No space has been found. Just terminate at our current + * location. This usually happens for languages that do not + * require spaces in strings, like Chinese, Japanese and + * Korean. For other languages terminating mid-word might + * not be the best, but terminating the whole string instead + * of continuing the word at the next line is worse. */ + last_char = this->buffer; + } else { + /* A space is found; perfect place to terminate */ + this->buffer = last_space + 1; + last_char = last_space; + } + break; + } + } + + this->buffer++; + } + + if (l->size() == 0 || last_char - begin > 0) { + int w = l->GetWidth(); + l->emplace_back(iter->second, begin, last_char - begin, w); + } + return l; +} diff --git a/src/gfx_layout_fallback.h b/src/gfx_layout_fallback.h new file mode 100644 index 0000000000..15927ac001 --- /dev/null +++ b/src/gfx_layout_fallback.h @@ -0,0 +1,30 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file gfx_layout_fallback.h Functions related to laying out the texts as fallback. */ + +#ifndef GFX_LAYOUT_FALLBACK_H +#define GFX_LAYOUT_FALLBACK_H + +#include "gfx_layout.h" + +/** + * Helper class to construct a new #FallbackParagraphLayout. + */ +class FallbackParagraphLayoutFactory { +public: + /** Helper for GetLayouter, to get the right type. */ + typedef WChar CharType; + /** Helper for GetLayouter, to get whether the layouter supports RTL. */ + static const bool SUPPORTS_RTL = false; + + static ParagraphLayouter *GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping); + static size_t AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c); +}; + + +#endif /* GFX_LAYOUT_FALLBACK_H */ diff --git a/src/gfx_layout_icu.cpp b/src/gfx_layout_icu.cpp new file mode 100644 index 0000000000..f88ab51330 --- /dev/null +++ b/src/gfx_layout_icu.cpp @@ -0,0 +1,181 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file gfx_layout_icu.cpp Handling of laying out text with ICU. */ + +#include "stdafx.h" + +#include "gfx_layout_icu.h" + +#include + +#include "safeguards.h" + +/* Implementation details of LEFontInstance */ + +le_int32 Font::getUnitsPerEM() const +{ + return this->fc->GetUnitsPerEM(); +} + +le_int32 Font::getAscent() const +{ + return this->fc->GetAscender(); +} + +le_int32 Font::getDescent() const +{ + return -this->fc->GetDescender(); +} + +le_int32 Font::getLeading() const +{ + return this->fc->GetHeight(); +} + +float Font::getXPixelsPerEm() const +{ + return (float)this->fc->GetHeight(); +} + +float Font::getYPixelsPerEm() const +{ + return (float)this->fc->GetHeight(); +} + +float Font::getScaleFactorX() const +{ + return 1.0f; +} + +float Font::getScaleFactorY() const +{ + return 1.0f; +} + +const void *Font::getFontTable(LETag tableTag) const +{ + size_t length; + return this->getFontTable(tableTag, length); +} + +const void *Font::getFontTable(LETag tableTag, size_t &length) const +{ + return this->fc->GetFontTable(tableTag, length); +} + +LEGlyphID Font::mapCharToGlyph(LEUnicode32 ch) const +{ + if (IsTextDirectionChar(ch)) return 0; + return this->fc->MapCharToGlyph(ch); +} + +void Font::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const +{ + advance.fX = glyph == 0xFFFF ? 0 : this->fc->GetGlyphWidth(glyph); + advance.fY = 0; +} + +le_bool Font::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const +{ + return false; +} + +/** + * Wrapper for doing layouts with ICU. + */ +class ICUParagraphLayout : public ParagraphLayouter { + icu::ParagraphLayout *p; ///< The actual ICU paragraph layout. +public: + /** Visual run contains data about the bit of text with the same font. */ + class ICUVisualRun : public ParagraphLayouter::VisualRun { + const icu::ParagraphLayout::VisualRun *vr; ///< The actual ICU vr. + + public: + ICUVisualRun(const icu::ParagraphLayout::VisualRun *vr) : vr(vr) { } + + const Font *GetFont() const override { return (const Font*)vr->getFont(); } + int GetGlyphCount() const override { return vr->getGlyphCount(); } + const GlyphID *GetGlyphs() const override { return vr->getGlyphs(); } + const float *GetPositions() const override { return vr->getPositions(); } + int GetLeading() const override { return vr->getLeading(); } + const int *GetGlyphToCharMap() const override { return vr->getGlyphToCharMap(); } + }; + + /** A single line worth of VisualRuns. */ + class ICULine : public std::vector, public ParagraphLayouter::Line { + icu::ParagraphLayout::Line *l; ///< The actual ICU line. + + public: + ICULine(icu::ParagraphLayout::Line *l) : l(l) + { + for (int i = 0; i < l->countRuns(); i++) { + this->emplace_back(l->getVisualRun(i)); + } + } + ~ICULine() override { delete l; } + + int GetLeading() const override { return l->getLeading(); } + int GetWidth() const override { return l->getWidth(); } + int CountRuns() const override { return l->countRuns(); } + const ParagraphLayouter::VisualRun &GetVisualRun(int run) const override { return this->at(run); } + + int GetInternalCharLength(WChar c) const override + { + /* ICU uses UTF-16 internally which means we need to account for surrogate pairs. */ + return Utf8CharLen(c) < 4 ? 1 : 2; + } + }; + + ICUParagraphLayout(icu::ParagraphLayout *p) : p(p) { } + ~ICUParagraphLayout() override { delete p; } + void Reflow() override { p->reflow(); } + + std::unique_ptr NextLine(int max_width) override + { + icu::ParagraphLayout::Line *l = p->nextLine(max_width); + return std::unique_ptr(l == nullptr ? nullptr : new ICULine(l)); + } +}; + +/* static */ ParagraphLayouter *ICUParagraphLayoutFactory::GetParagraphLayout(UChar *buff, UChar *buff_end, FontMap &fontMapping) +{ + int32 length = buff_end - buff; + + if (length == 0) { + /* ICU's ParagraphLayout cannot handle empty strings, so fake one. */ + buff[0] = ' '; + length = 1; + fontMapping.back().first++; + } + + /* Fill ICU's FontRuns with the right data. */ + icu::FontRuns runs(fontMapping.size()); + for (auto &pair : fontMapping) { + runs.add(pair.second, pair.first); + } + + LEErrorCode status = LE_NO_ERROR; + /* ParagraphLayout does not copy "buff", so it must stay valid. + * "runs" is copied according to the ICU source, but the documentation does not specify anything, so this might break somewhen. */ + icu::ParagraphLayout *p = new icu::ParagraphLayout(buff, length, &runs, nullptr, nullptr, nullptr, _current_text_dir == TD_RTL ? 1 : 0, false, status); + if (status != LE_NO_ERROR) { + delete p; + return nullptr; + } + + return new ICUParagraphLayout(p); +} + +/* static */ size_t ICUParagraphLayoutFactory::AppendToBuffer(UChar *buff, const UChar *buffer_last, WChar c) +{ + /* Transform from UTF-32 to internal ICU format of UTF-16. */ + int32 length = 0; + UErrorCode err = U_ZERO_ERROR; + u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err); + return length; +} diff --git a/src/gfx_layout_icu.h b/src/gfx_layout_icu.h new file mode 100644 index 0000000000..cdebcbc0b4 --- /dev/null +++ b/src/gfx_layout_icu.h @@ -0,0 +1,30 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file gfx_layout_icu.h Functions related to laying out the texts with ICU. */ + +#ifndef GFX_LAYOUT_ICU_H +#define GFX_LAYOUT_ICU_H + +#include "gfx_layout.h" +#include + +/** + * Helper class to construct a new #ICUParagraphLayout. + */ +class ICUParagraphLayoutFactory { +public: + /** Helper for GetLayouter, to get the right type. */ + typedef UChar CharType; + /** Helper for GetLayouter, to get whether the layouter supports RTL. */ + static const bool SUPPORTS_RTL = true; + + static ParagraphLayouter *GetParagraphLayout(UChar *buff, UChar *buff_end, FontMap &fontMapping); + static size_t AppendToBuffer(UChar *buff, const UChar *buffer_last, WChar c); +}; + +#endif /* GFX_LAYOUT_ICU_H */ From 81d4fa69990abbc18bd83d60658b0eedd66b7447 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 30 Apr 2023 20:37:40 +0200 Subject: [PATCH 04/34] Feature: drop ICU-lx in favour of directly interfacing with harfbuzz This means we have RTL support again with ICU 58+. It makes use of: - ICU for bidi-itemization - ICU for script-itemization - OpenTTD for style-itemization - harfbuzz for shaping --- .github/workflows/ci-build.yml | 1 + .github/workflows/release-linux.yml | 15 +- CMakeLists.txt | 11 +- COMPILING.md | 1 + Doxyfile.in | 2 +- README.md | 3 + cmake/FindHarfbuzz.cmake | 65 ++++ cmake/FindICU.cmake | 4 +- src/3rdparty/CMakeLists.txt | 1 + src/3rdparty/icu/CMakeLists.txt | 5 + src/3rdparty/icu/LICENSE | 46 +++ src/3rdparty/icu/scriptrun.cpp | 208 ++++++++++ src/3rdparty/icu/scriptrun.h | 159 ++++++++ src/CMakeLists.txt | 2 +- src/crashlog.cpp | 20 +- src/fontcache/freetypefontcache.cpp | 13 +- src/gfx_layout.cpp | 26 +- src/gfx_layout.h | 29 +- src/gfx_layout_fallback.cpp | 3 +- src/gfx_layout_icu.cpp | 573 ++++++++++++++++++++++------ src/gfx_layout_icu.h | 1 + src/strings.cpp | 6 +- 22 files changed, 1011 insertions(+), 183 deletions(-) create mode 100644 cmake/FindHarfbuzz.cmake create mode 100644 src/3rdparty/icu/CMakeLists.txt create mode 100644 src/3rdparty/icu/LICENSE create mode 100644 src/3rdparty/icu/scriptrun.cpp create mode 100644 src/3rdparty/icu/scriptrun.h diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index f02a926a4c..c187e00e35 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -113,6 +113,7 @@ jobs: liballegro4-dev \ libcurl4-openssl-dev \ libfontconfig-dev \ + libharfbuzz-dev \ libicu-dev \ liblzma-dev \ liblzo2-dev \ diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index 048e1b0710..5ab2bcd9e6 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -34,15 +34,20 @@ jobs: - name: Install dependencies run: | echo "::group::Install system dependencies" - # ICU is used as vcpkg fails to install ICU. Other dependencies - # are needed either for vcpkg or for the packages installed with - # vcpkg. + # perl-IPC-Cmd, wget, and zip are needed to run vcpkg. + # autoconf-archive is needed to build ICU. yum install -y \ - libicu-devel \ + autoconf-archive \ perl-IPC-Cmd \ wget \ zip \ # EOF + + # aclocal looks first in /usr/local/share/aclocal, and if that doesn't + # exist only looks in /usr/share/aclocal. We have files in both that + # are important. So copy the latter to the first, and we are good to + # go. + cp /usr/share/aclocal/* /usr/local/share/aclocal/ echo "::endgroup::" # We use vcpkg for our dependencies, to get more up-to-date version. @@ -69,6 +74,8 @@ jobs: curl[http2] \ fontconfig \ freetype \ + harfbuzz \ + icu \ liblzma \ libpng \ lzo \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 655f4c144f..0ae67f5280 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,7 +143,8 @@ if(NOT OPTION_DEDICATED) endif() find_package(Fluidsynth) find_package(Fontconfig) - find_package(ICU OPTIONAL_COMPONENTS i18n lx) + find_package(Harfbuzz) + find_package(ICU OPTIONAL_COMPONENTS i18n) endif() endif() endif() @@ -178,6 +179,12 @@ if(UNIX AND NOT APPLE AND NOT OPTION_DEDICATED) if(NOT SDL_FOUND AND NOT SDL2_FOUND AND NOT ALLEGRO_FOUND) message(FATAL_ERROR "SDL, SDL2 or Allegro is required for this platform") endif() + if(HARFBUZZ_FOUND AND NOT ICU_i18n_FOUND) + message(WARNING "HarfBuzz depends on ICU i18n to function; HarfBuzz will be disabled") + endif() + if(NOT HARFBUZZ_FOUND) + message(WARNING "Without HarfBuzz and ICU i18n the game will not be able to render right-to-left languages correctly") + endif() endif() if(APPLE) if(NOT AUDIOTOOLBOX_LIBRARY) @@ -289,7 +296,7 @@ if(NOT OPTION_DEDICATED) link_package(Allegro) link_package(FREETYPE TARGET Freetype::Freetype) link_package(Fontconfig TARGET Fontconfig::Fontconfig) - link_package(ICU_lx) + link_package(Harfbuzz TARGET harfbuzz::harfbuzz) link_package(ICU_i18n) if(SDL2_FOUND AND OPENGL_FOUND AND UNIX) diff --git a/COMPILING.md b/COMPILING.md index 5b1d457224..551afe39cb 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -16,6 +16,7 @@ For Linux, the following additional libraries are used: - libSDL2: hardware access (video, sound, mouse) - libfreetype: loading generic fonts and rendering them - libfontconfig: searching for fonts, resolving font names to actual fonts +- harfbuzz: handling of right-to-left scripts (e.g. Arabic and Persian) (required libicu) - libicu: handling of right-to-left scripts (e.g. Arabic and Persian) and natural sorting of strings diff --git a/Doxyfile.in b/Doxyfile.in index 51a44526c3..4e287889af 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -292,8 +292,8 @@ PREDEFINED = WITH_ZLIB \ WITH_PNG \ WITH_FONTCONFIG \ WITH_FREETYPE \ + WITH_HARFBUZZ \ WITH_ICU_I18N \ - WITH_ICU_LX \ UNICODE \ _UNICODE \ _GNU_SOURCE \ diff --git a/README.md b/README.md index 466868c860..6f86b5ae3f 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,9 @@ See `src/3rdparty/fmt/LICENSE.rst` for the complete license text. The catch2 implementation in `src/3rdparty/catch2` is licensed under the Boost Software License, Version 1.0. See `src/3rdparty/catch2/LICENSE.txt` for the complete license text. +The icu scriptrun implementation in `src/3rdparty/icu` is licensed under the Unicode license. +See `src/3rdparty/icu/LICENSE` for the complete license text. + ## 4.0 Credits See [CREDITS.md](./CREDITS.md) diff --git a/cmake/FindHarfbuzz.cmake b/cmake/FindHarfbuzz.cmake new file mode 100644 index 0000000000..11a4dcb303 --- /dev/null +++ b/cmake/FindHarfbuzz.cmake @@ -0,0 +1,65 @@ +#[=======================================================================[.rst: +FindHarfBuzz +------- + +Finds the harfbuzz library. + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``Harfbuzz_FOUND`` + True if the system has the harfbuzz library. +``Harfbuzz_INCLUDE_DIRS`` + Include directories needed to use harfbuzz. +``Harfbuzz_LIBRARIES`` + Libraries needed to link to harfbuzz. +``Harfbuzz_VERSION`` + The version of the harfbuzz library which was found. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``Harfbuzz_INCLUDE_DIR`` + The directory containing ``hb.h``. +``Harfbuzz_LIBRARY`` + The path to the harfbuzz library. + +#]=======================================================================] + +find_package(PkgConfig QUIET) +pkg_check_modules(PC_Harfbuzz QUIET harfbuzz) + +find_path(Harfbuzz_INCLUDE_DIR + NAMES hb.h + PATHS ${PC_Harfbuzz_INCLUDE_DIRS} +) + +find_library(Harfbuzz_LIBRARY + NAMES harfbuzz + PATHS ${PC_Harfbuzz_LIBRARY_DIRS} +) + +set(Harfbuzz_VERSION ${PC_Harfbuzz_VERSION}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Harfbuzz + FOUND_VAR Harfbuzz_FOUND + REQUIRED_VARS + Harfbuzz_LIBRARY + Harfbuzz_INCLUDE_DIR + VERSION_VAR Harfbuzz_VERSION +) + +if(Harfbuzz_FOUND) + set(Harfbuzz_LIBRARIES ${Harfbuzz_LIBRARY}) + set(Harfbuzz_INCLUDE_DIRS ${Harfbuzz_INCLUDE_DIR}) +endif() + +mark_as_advanced( + Harfbuzz_INCLUDE_DIR + Harfbuzz_LIBRARY +) diff --git a/cmake/FindICU.cmake b/cmake/FindICU.cmake index d12f36b0ad..efb3ba3abf 100644 --- a/cmake/FindICU.cmake +++ b/cmake/FindICU.cmake @@ -9,7 +9,7 @@ FindICU Finds components of the ICU library. -Accepted components are: uc, i18n, le, lx, io +Accepted components are: uc, i18n, le, lx, io, data Result Variables ^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ This will define the following variables: find_package(PkgConfig QUIET) -set(ICU_KNOWN_COMPONENTS "uc" "i18n" "le" "lx" "io") +set(ICU_KNOWN_COMPONENTS "uc" "i18n" "le" "lx" "io" "data") foreach(MOD_NAME IN LISTS ICU_FIND_COMPONENTS) if(NOT MOD_NAME IN_LIST ICU_KNOWN_COMPONENTS) diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index 1c7f915de6..051ec193ba 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(catch2) add_subdirectory(fmt) +add_subdirectory(icu) add_subdirectory(md5) add_subdirectory(squirrel) add_subdirectory(opengl) diff --git a/src/3rdparty/icu/CMakeLists.txt b/src/3rdparty/icu/CMakeLists.txt new file mode 100644 index 0000000000..09afc44926 --- /dev/null +++ b/src/3rdparty/icu/CMakeLists.txt @@ -0,0 +1,5 @@ +add_files( + scriptrun.cpp + scriptrun.h + CONDITION ICU_i18n_FOUND +) diff --git a/src/3rdparty/icu/LICENSE b/src/3rdparty/icu/LICENSE new file mode 100644 index 0000000000..e216c7f3ad --- /dev/null +++ b/src/3rdparty/icu/LICENSE @@ -0,0 +1,46 @@ +UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE + +See Terms of Use +for definitions of Unicode Inc.’s Data Files and Software. + +NOTICE TO USER: Carefully read the following legal agreement. +BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. +IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +THE DATA FILES OR SOFTWARE. + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 1991-2023 Unicode, Inc. All rights reserved. +Distributed under the Terms of Use in https://www.unicode.org/copyright.html. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Unicode data files and any associated documentation +(the "Data Files") or Unicode software and any associated documentation +(the "Software") to deal in the Data Files or Software +without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, and/or sell copies of +the Data Files or Software, and to permit persons to whom the Data Files +or Software are furnished to do so, provided that either +(a) this copyright and permission notice appear with all copies +of the Data Files or Software, or +(b) this copyright and permission notice appear in associated +Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT OF THIRD PARTY RIGHTS. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THE DATA FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in these Data Files or Software without prior +written authorization of the copyright holder. diff --git a/src/3rdparty/icu/scriptrun.cpp b/src/3rdparty/icu/scriptrun.cpp new file mode 100644 index 0000000000..d0ed37dcb9 --- /dev/null +++ b/src/3rdparty/icu/scriptrun.cpp @@ -0,0 +1,208 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* + ******************************************************************************* + * + * Copyright (C) 1999-2016, International Business Machines + * Corporation and others. All Rights Reserved. + * + ******************************************************************************* + * file name: scrptrun.cpp + * + * created on: 10/17/2001 + * created by: Eric R. Mader + */ + +#include +#include + +#include "scriptrun.h" + +// Copied from cmemory.h +#define UPRV_LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) + +U_NAMESPACE_BEGIN + +const char ScriptRun::fgClassID=0; + +UChar32 ScriptRun::pairedChars[] = { + 0x0028, 0x0029, // ascii paired punctuation + 0x003c, 0x003e, + 0x005b, 0x005d, + 0x007b, 0x007d, + 0x00ab, 0x00bb, // guillemets + 0x2018, 0x2019, // general punctuation + 0x201c, 0x201d, + 0x2039, 0x203a, + 0x3008, 0x3009, // chinese paired punctuation + 0x300a, 0x300b, + 0x300c, 0x300d, + 0x300e, 0x300f, + 0x3010, 0x3011, + 0x3014, 0x3015, + 0x3016, 0x3017, + 0x3018, 0x3019, + 0x301a, 0x301b +}; + +const int32_t ScriptRun::pairedCharCount = UPRV_LENGTHOF(pairedChars); +const int32_t ScriptRun::pairedCharPower = 1 << highBit(pairedCharCount); +const int32_t ScriptRun::pairedCharExtra = pairedCharCount - pairedCharPower; + +int8_t ScriptRun::highBit(int32_t value) +{ + if (value <= 0) { + return -32; + } + + int8_t bit = 0; + + if (value >= 1 << 16) { + value >>= 16; + bit += 16; + } + + if (value >= 1 << 8) { + value >>= 8; + bit += 8; + } + + if (value >= 1 << 4) { + value >>= 4; + bit += 4; + } + + if (value >= 1 << 2) { + value >>= 2; + bit += 2; + } + + if (value >= 1 << 1) { + value >>= 1; + bit += 1; + } + + return bit; +} + +int32_t ScriptRun::getPairIndex(UChar32 ch) +{ + int32_t probe = pairedCharPower; + int32_t index = 0; + + if (ch >= pairedChars[pairedCharExtra]) { + index = pairedCharExtra; + } + + while (probe > (1 << 0)) { + probe >>= 1; + + if (ch >= pairedChars[index + probe]) { + index += probe; + } + } + + if (pairedChars[index] != ch) { + index = -1; + } + + return index; +} + +UBool ScriptRun::sameScript(int32_t scriptOne, int32_t scriptTwo) +{ + return scriptOne <= USCRIPT_INHERITED || scriptTwo <= USCRIPT_INHERITED || scriptOne == scriptTwo; +} + +UBool ScriptRun::next() +{ + int32_t startSP = parenSP; // used to find the first new open character + UErrorCode error = U_ZERO_ERROR; + + // if we've fallen off the end of the text, we're done + if (scriptEnd >= charLimit) { + return false; + } + + scriptCode = USCRIPT_COMMON; + + for (scriptStart = scriptEnd; scriptEnd < charLimit; scriptEnd += 1) { + char16_t high = charArray[scriptEnd]; + UChar32 ch = high; + + // if the character is a high surrogate and it's not the last one + // in the text, see if it's followed by a low surrogate + if (high >= 0xD800 && high <= 0xDBFF && scriptEnd < charLimit - 1) + { + char16_t low = charArray[scriptEnd + 1]; + + // if it is followed by a low surrogate, + // consume it and form the full character + if (low >= 0xDC00 && low <= 0xDFFF) { + ch = (high - 0xD800) * 0x0400 + low - 0xDC00 + 0x10000; + scriptEnd += 1; + } + } + + UScriptCode sc = uscript_getScript(ch, &error); + int32_t pairIndex = getPairIndex(ch); + + // Paired character handling: + // + // if it's an open character, push it onto the stack. + // if it's a close character, find the matching open on the + // stack, and use that script code. Any non-matching open + // characters above it on the stack will be poped. + if (pairIndex >= 0) { + if ((pairIndex & 1) == 0) { + parenStack[++parenSP].pairIndex = pairIndex; + parenStack[parenSP].scriptCode = scriptCode; + } else if (parenSP >= 0) { + int32_t pi = pairIndex & ~1; + + while (parenSP >= 0 && parenStack[parenSP].pairIndex != pi) { + parenSP -= 1; + } + + if (parenSP < startSP) { + startSP = parenSP; + } + + if (parenSP >= 0) { + sc = parenStack[parenSP].scriptCode; + } + } + } + + if (sameScript(scriptCode, sc)) { + if (scriptCode <= USCRIPT_INHERITED && sc > USCRIPT_INHERITED) { + scriptCode = sc; + + // now that we have a final script code, fix any open + // characters we pushed before we knew the script code. + while (startSP < parenSP) { + parenStack[++startSP].scriptCode = scriptCode; + } + } + + // if this character is a close paired character, + // pop it from the stack + if (pairIndex >= 0 && (pairIndex & 1) != 0 && parenSP >= 0) { + parenSP -= 1; + startSP -= 1; + } + } else { + // if the run broke on a surrogate pair, + // end it before the high surrogate + if (ch >= 0x10000) { + scriptEnd -= 1; + } + + break; + } + } + + return true; +} + +U_NAMESPACE_END diff --git a/src/3rdparty/icu/scriptrun.h b/src/3rdparty/icu/scriptrun.h new file mode 100644 index 0000000000..0a00001052 --- /dev/null +++ b/src/3rdparty/icu/scriptrun.h @@ -0,0 +1,159 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* + ******************************************************************************* + * + * Copyright (C) 1999-2003, International Business Machines + * Corporation and others. All Rights Reserved. + * + ******************************************************************************* + * file name: scrptrun.h + * + * created on: 10/17/2001 + * created by: Eric R. Mader + */ + +#ifndef __SCRPTRUN_H +#define __SCRPTRUN_H + +#include +#include +#include + +U_NAMESPACE_BEGIN + +struct ScriptRecord +{ + UChar32 startChar; + UChar32 endChar; + UScriptCode scriptCode; +}; + +struct ParenStackEntry +{ + int32_t pairIndex; + UScriptCode scriptCode; +}; + +class ScriptRun : public UObject { +public: + ScriptRun(); + + ScriptRun(const char16_t *chars, int32_t length); + + ScriptRun(const char16_t *chars, int32_t start, int32_t length); + + void reset(); + + void reset(int32_t start, int32_t count); + + void reset(const char16_t *chars, int32_t start, int32_t length); + + int32_t getScriptStart(); + + int32_t getScriptEnd(); + + UScriptCode getScriptCode(); + + UBool next(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.2 + */ + virtual inline UClassID getDynamicClassID() const override { return getStaticClassID(); } + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.2 + */ + static inline UClassID getStaticClassID() { return (UClassID)const_cast(&fgClassID); } + +private: + + static UBool sameScript(int32_t scriptOne, int32_t scriptTwo); + + int32_t charStart; + int32_t charLimit; + const char16_t *charArray; + + int32_t scriptStart; + int32_t scriptEnd; + UScriptCode scriptCode; + + ParenStackEntry parenStack[128]; + int32_t parenSP; + + static int8_t highBit(int32_t value); + static int32_t getPairIndex(UChar32 ch); + + static UChar32 pairedChars[]; + static const int32_t pairedCharCount; + static const int32_t pairedCharPower; + static const int32_t pairedCharExtra; + + /** + * The address of this static class variable serves as this class's ID + * for ICU "poor man's RTTI". + */ + static const char fgClassID; +}; + +inline ScriptRun::ScriptRun() +{ + reset(nullptr, 0, 0); +} + +inline ScriptRun::ScriptRun(const char16_t *chars, int32_t length) +{ + reset(chars, 0, length); +} + +inline ScriptRun::ScriptRun(const char16_t *chars, int32_t start, int32_t length) +{ + reset(chars, start, length); +} + +inline int32_t ScriptRun::getScriptStart() +{ + return scriptStart; +} + +inline int32_t ScriptRun::getScriptEnd() +{ + return scriptEnd; +} + +inline UScriptCode ScriptRun::getScriptCode() +{ + return scriptCode; +} + +inline void ScriptRun::reset() +{ + scriptStart = charStart; + scriptEnd = charStart; + scriptCode = USCRIPT_INVALID_CODE; + parenSP = -1; +} + +inline void ScriptRun::reset(int32_t start, int32_t length) +{ + charStart = start; + charLimit = start + length; + + reset(); +} + +inline void ScriptRun::reset(const char16_t *chars, int32_t start, int32_t length) +{ + charArray = chars; + + reset(start, length); +} + +U_NAMESPACE_END + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce078a02af..01fbf2f0cb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,7 +36,7 @@ add_files( add_files( gfx_layout_icu.cpp gfx_layout_icu.h - CONDITION ICU_lx_FOUND + CONDITION ICU_i18n_FOUND AND HARFBUZZ_FOUND ) add_files( diff --git a/src/crashlog.cpp b/src/crashlog.cpp index 05f09d6dee..d1bf8cfd54 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -50,9 +50,12 @@ # include # include FT_FREETYPE_H #endif /* WITH_FREETYPE */ -#if defined(WITH_ICU_LX) || defined(WITH_ICU_I18N) +#ifdef WITH_HARFBUZZ +# include +#endif /* WITH_HARFBUZZ */ +#ifdef WITH_ICU_I18N # include -#endif /* WITH_ICU_LX || WITH_ICU_I18N */ +#endif /* WITH_ICU_I18N */ #ifdef WITH_LIBLZMA # include #endif @@ -238,19 +241,18 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const buffer += seprintf(buffer, last, " FreeType: %d.%d.%d\n", major, minor, patch); #endif /* WITH_FREETYPE */ -#if defined(WITH_ICU_LX) || defined(WITH_ICU_I18N) +#if defined(WITH_HARFBUZZ) + buffer += seprintf(buffer, last, " HarfBuzz: %s\n", hb_version_string()); +#endif /* WITH_HARFBUZZ */ + +#if defined(WITH_ICU_I18N) /* 4 times 0-255, separated by dots (.) and a trailing '\0' */ char buf[4 * 3 + 3 + 1]; UVersionInfo ver; u_getVersion(ver); u_versionToString(ver, buf); -#ifdef WITH_ICU_I18N buffer += seprintf(buffer, last, " ICU i18n: %s\n", buf); -#endif -#ifdef WITH_ICU_LX - buffer += seprintf(buffer, last, " ICU lx: %s\n", buf); -#endif -#endif /* WITH_ICU_LX || WITH_ICU_I18N */ +#endif /* WITH_ICU_I18N */ #ifdef WITH_LIBLZMA buffer += seprintf(buffer, last, " LZMA: %s\n", lzma_version_string()); diff --git a/src/fontcache/freetypefontcache.cpp b/src/fontcache/freetypefontcache.cpp index 40d1ba9db5..0a8a1af53f 100644 --- a/src/fontcache/freetypefontcache.cpp +++ b/src/fontcache/freetypefontcache.cpp @@ -34,16 +34,17 @@ private: FT_Face face; ///< The font face associated with this font. void SetFontSize(FontSize fs, FT_Face face, int pixels); - virtual const void *InternalGetFontTable(uint32 tag, size_t &length); - virtual const Sprite *InternalGetGlyph(GlyphID key, bool aa); + const void *InternalGetFontTable(uint32 tag, size_t &length) override; + const Sprite *InternalGetGlyph(GlyphID key, bool aa) override; public: FreeTypeFontCache(FontSize fs, FT_Face face, int pixels); ~FreeTypeFontCache(); - virtual void ClearFontCache(); - virtual GlyphID MapCharToGlyph(WChar key); - virtual const char *GetFontName() { return face->family_name; } - virtual bool IsBuiltInFont() { return false; } + void ClearFontCache() override; + GlyphID MapCharToGlyph(WChar key) override; + const char *GetFontName() override { return face->family_name; } + bool IsBuiltInFont() override { return false; } + const void *GetOSHandle() override { return &face; } }; FT_Library _library = nullptr; diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index ab40b55737..6ddb0c4b85 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -10,17 +10,15 @@ #include "stdafx.h" #include "gfx_layout.h" #include "string_func.h" -#include "strings_func.h" -#include "zoom_func.h" #include "debug.h" #include "table/control_codes.h" #include "gfx_layout_fallback.h" -#ifdef WITH_ICU_LX +#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ) #include "gfx_layout_icu.h" -#endif /* WITH_ICU_LX */ +#endif /* WITH_ICU_I18N && WITH_HARFBUZZ */ #ifdef WITH_UNISCRIBE #include "os/windows/string_uniscribe.h" @@ -95,8 +93,8 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str, /* Filter out non printable characters */ if (!IsPrintable(c)) continue; /* Filter out text direction characters that shouldn't be drawn, and - * will not be handled in the fallback non ICU case because they are - * mostly needed for RTL languages which need more ICU support. */ + * will not be handled in the fallback case because they are mostly + * needed for RTL languages which need more proper shaping support. */ if (!T::SUPPORTS_RTL && IsTextDirectionChar(c)) continue; buff += T::AppendToBuffer(buff, buffer_last, c); continue; @@ -148,21 +146,17 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi } else { /* Line is new, layout it */ FontState old_state = state; -#if defined(WITH_ICU_LX) || defined(WITH_UNISCRIBE) || defined(WITH_COCOA) +#if (defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)) || defined(WITH_UNISCRIBE) || defined(WITH_COCOA) const char *old_str = str; #endif -#ifdef WITH_ICU_LX - GetLayouter(line, str, state); +#if defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ) if (line.layout == nullptr) { - static bool warned = false; - if (!warned) { - Debug(misc, 0, "ICU layouter bailed on the font. Falling back to the fallback layouter"); - warned = true; + GetLayouter(line, str, state); + if (line.layout == nullptr) { + state = old_state; + str = old_str; } - - state = old_state; - str = old_str; } #endif diff --git a/src/gfx_layout.h b/src/gfx_layout.h index c9790556ea..47eb60544e 100644 --- a/src/gfx_layout.h +++ b/src/gfx_layout.h @@ -21,13 +21,6 @@ #include #include -#ifdef WITH_ICU_LX -#include "layout/ParagraphLayout.h" -#define ICU_FONTINSTANCE : public icu::LEFontInstance -#else /* WITH_ICU_LX */ -#define ICU_FONTINSTANCE -#endif /* WITH_ICU_LX */ - /** * Text drawing parameters, which can change while drawing a line, but are kept between multiple parts * of the same text, e.g. on line breaks. @@ -83,30 +76,12 @@ struct FontState { /** * Container with information about a font. */ -class Font ICU_FONTINSTANCE { +class Font { public: FontCache *fc; ///< The font we are using. TextColour colour; ///< The colour this font has to be. Font(FontSize size, TextColour colour); - -#ifdef WITH_ICU_LX - /* Implementation details of LEFontInstance */ - - le_int32 getUnitsPerEM() const; - le_int32 getAscent() const; - le_int32 getDescent() const; - le_int32 getLeading() const; - float getXPixelsPerEm() const; - float getYPixelsPerEm() const; - float getScaleFactorX() const; - float getScaleFactorY() const; - const void *getFontTable(LETag tableTag) const; - const void *getFontTable(LETag tableTag, size_t &length) const; - LEGlyphID mapCharToGlyph(LEUnicode32 ch) const; - void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const; - le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const; -#endif /* WITH_ICU_LX */ }; /** Mapping from index to font. */ @@ -183,7 +158,7 @@ public: /** Item in the linecache */ struct LineCacheItem { /* Stuff that cannot be freed until the ParagraphLayout is freed */ - void *buffer; ///< Accessed by both ICU's and our ParagraphLayout::nextLine. + void *buffer; ///< Accessed by our ParagraphLayout::nextLine. FontMap runs; ///< Accessed by our ParagraphLayout::nextLine. FontState state_after; ///< Font state after the line. diff --git a/src/gfx_layout_fallback.cpp b/src/gfx_layout_fallback.cpp index 2274ad1637..dbb2f0cc28 100644 --- a/src/gfx_layout_fallback.cpp +++ b/src/gfx_layout_fallback.cpp @@ -33,8 +33,7 @@ * The positions in a visual run are sequential pairs of X,Y of the * begin of each of the glyphs plus an extra pair to mark the end. * - * @note This variant does not handle left-to-right properly. This - * is supported in the one ParagraphLayout coming from ICU. + * @note This variant does not handle right-to-left properly. */ class FallbackParagraphLayout : public ParagraphLayouter { public: diff --git a/src/gfx_layout_icu.cpp b/src/gfx_layout_icu.cpp index f88ab51330..c7bdf1016f 100644 --- a/src/gfx_layout_icu.cpp +++ b/src/gfx_layout_icu.cpp @@ -5,170 +5,523 @@ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . */ -/** @file gfx_layout_icu.cpp Handling of laying out text with ICU. */ +/** @file gfx_layout_icu.cpp Handling of laying out with ICU / Harfbuzz. */ #include "stdafx.h" - #include "gfx_layout_icu.h" -#include +#include "debug.h" +#include "strings_func.h" +#include "language.h" +#include "table/control_codes.h" +#include "zoom_func.h" + +#include "3rdparty/icu/scriptrun.h" + +#include +#include + +#include +#include + +#include #include "safeguards.h" -/* Implementation details of LEFontInstance */ +/** harfbuzz doesn't use floats, so we need a value to scale position with to get sub-pixel precision. */ +constexpr float FONT_SCALE = 64.0; -le_int32 Font::getUnitsPerEM() const -{ - return this->fc->GetUnitsPerEM(); -} +/** + * Helper class to store the information of all the runs of a paragraph in. + * + * During itemization, more and more information is filled in. + */ +class ICURun { +public: + int start; ///< Start of the run in the buffer. + int length; ///< Length of the run in the buffer. + UBiDiLevel level; ///< Embedding level of the run. + UScriptCode script; ///< Script of the run. + Font *font; ///< Font of the run. -le_int32 Font::getAscent() const -{ - return this->fc->GetAscender(); -} + std::vector glyphs; ///< The glyphs of the run. Valid after Shape() is called. + std::vector advance; ///< The advance (width) of the glyphs. Valid after Shape() is called. + std::vector glyph_to_char; ///< The mapping from glyphs to characters. Valid after Shape() is called. + std::vector positions; ///< The positions of the glyphs. Valid after Shape() is called. + int total_advance; ///< The total advance of the run. Valid after Shape() is called. -le_int32 Font::getDescent() const -{ - return -this->fc->GetDescender(); -} + ICURun(int start, int length, UBiDiLevel level, UScriptCode script = USCRIPT_UNKNOWN, Font *font = nullptr) : start(start), length(length), level(level), script(script), font(font) {} -le_int32 Font::getLeading() const -{ - return this->fc->GetHeight(); -} + void Shape(UChar *buff, size_t length); +}; -float Font::getXPixelsPerEm() const -{ - return (float)this->fc->GetHeight(); -} +/** + * Wrapper for doing layouts with ICU. + */ +class ICUParagraphLayout : public ParagraphLayouter { +public: + /** Visual run contains data about the bit of text with the same font. */ + class ICUVisualRun : public ParagraphLayouter::VisualRun { + private: + std::vector glyphs; + std::vector positions; + std::vector glyph_to_char; + + int total_advance; + const Font *font; + + public: + ICUVisualRun(const ICURun &run, int x); + + const GlyphID *GetGlyphs() const override { return this->glyphs.data(); } + const float *GetPositions() const override { return this->positions.data(); } + const int *GetGlyphToCharMap() const override { return this->glyph_to_char.data(); } + + const Font *GetFont() const override { return this->font; } + int GetLeading() const override { return this->font->fc->GetHeight(); } + int GetGlyphCount() const override { return this->glyphs.size(); } + int GetAdvance() const { return this->total_advance; } + }; + + /** A single line worth of VisualRuns. */ + class ICULine : public std::vector, public ParagraphLayouter::Line { + public: + int GetLeading() const override; + int GetWidth() const override; + int CountRuns() const override { return (uint)this->size(); } + const VisualRun &GetVisualRun(int run) const override { return this->at(run); } + + int GetInternalCharLength(WChar c) const override + { + /* ICU uses UTF-16 internally which means we need to account for surrogate pairs. */ + return c >= 0x010000U ? 2 : 1; + } + }; + +private: + std::vector runs; + UChar *buff; + size_t buff_length; + std::vector::iterator current_run; + int partial_offset; + +public: + ICUParagraphLayout(std::vector &runs, UChar *buff, size_t buff_length) : runs(runs), buff(buff), buff_length(buff_length) + { + this->Reflow(); + } -float Font::getYPixelsPerEm() const + ~ICUParagraphLayout() override { } + + void Reflow() override + { + this->current_run = this->runs.begin(); + this->partial_offset = 0; + } + + std::unique_ptr NextLine(int max_width) override; +}; + +/** + * Constructor for a new ICUVisualRun. + * + * It bases all information on the ICURun, which should already be shaped. + * + * @param run The ICURun to base the visual run on. + * @param x The offset of the run on the line. + */ +ICUParagraphLayout::ICUVisualRun::ICUVisualRun(const ICURun &run, int x) : + glyphs(run.glyphs), glyph_to_char(run.glyph_to_char), total_advance(run.total_advance), font(run.font) { - return (float)this->fc->GetHeight(); + /* If there are no positions, the ICURun was not Shaped; that should never happen. */ + assert(run.positions.size() != 0); + this->positions.reserve(run.positions.size()); + + /* "positions" is an array of x/y. So we need to alternate. */ + bool is_x = true; + for (auto &position : run.positions) { + if (is_x) { + this->positions.push_back(position + x); + } else { + this->positions.push_back(position); + } + + is_x = !is_x; + } } -float Font::getScaleFactorX() const -{ - return 1.0f; +/** + * Shape a single run. + * + * @param buff The buffer of which a partial (depending on start/length of the run) will be shaped. + * @param length The length of the buffer. + */ +void ICURun::Shape(UChar *buff, size_t buff_length) { + auto hbfont = hb_ft_font_create_referenced(*(static_cast(font->fc->GetOSHandle()))); + hb_font_set_scale(hbfont, this->font->fc->GetFontSize() * FONT_SCALE, this->font->fc->GetFontSize() * FONT_SCALE); + + /* ICU buffer is in UTF-16. */ + auto hbbuf = hb_buffer_create(); + hb_buffer_add_utf16(hbbuf, reinterpret_cast(buff), buff_length, this->start, this->length); + + /* Set all the properties of this segment. */ + hb_buffer_set_direction(hbbuf, (this->level & 1) == 1 ? HB_DIRECTION_RTL : HB_DIRECTION_LTR); + hb_buffer_set_script(hbbuf, hb_script_from_string(uscript_getShortName(this->script), -1)); + hb_buffer_set_language(hbbuf, hb_language_from_string(_current_language->isocode, -1)); + hb_buffer_set_cluster_level(hbbuf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES); + + /* Shape the segment. */ + hb_shape(hbfont, hbbuf, nullptr, 0); + + unsigned int glyph_count; + auto glyph_info = hb_buffer_get_glyph_infos(hbbuf, &glyph_count); + auto glyph_pos = hb_buffer_get_glyph_positions(hbbuf, &glyph_count); + + /* Make sure any former run is lost. */ + this->glyphs.clear(); + this->glyph_to_char.clear(); + this->positions.clear(); + this->advance.clear(); + + /* Reserve space, as we already know the size. */ + this->glyphs.reserve(glyph_count); + this->glyph_to_char.reserve(glyph_count); + this->positions.reserve(glyph_count * 2 + 2); + this->advance.reserve(glyph_count); + + /* Prepare the glyphs/position. ICUVisualRun will give the position an offset if needed. */ + hb_position_t advance = 0; + for (unsigned int i = 0; i < glyph_count; i++) { + int x_advance; + + if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END) { + auto glyph = this->font->fc->MapCharToGlyph(buff[glyph_info[i].cluster]); + + this->glyphs.push_back(glyph); + this->positions.push_back(advance); + this->positions.push_back((this->font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->font->fc->GetSize()))) / 2); // Align sprite font to centre + x_advance = this->font->fc->GetGlyphWidth(glyph); + } else { + this->glyphs.push_back(glyph_info[i].codepoint); + this->positions.push_back(glyph_pos[i].x_offset / FONT_SCALE + advance); + this->positions.push_back(glyph_pos[i].y_offset / FONT_SCALE); + x_advance = glyph_pos[i].x_advance / FONT_SCALE; + } + + this->glyph_to_char.push_back(glyph_info[i].cluster); + this->advance.push_back(x_advance); + advance += x_advance; + } + + /* Position has one more element to close off the array. */ + this->positions.push_back(advance); + this->positions.push_back(0); + + /* Track the total advancement we made. */ + this->total_advance = advance; + + hb_buffer_destroy(hbbuf); + hb_font_destroy(hbfont); } -float Font::getScaleFactorY() const +/** + * Get the height of the line. + * @return The maximum height of the line. + */ +int ICUParagraphLayout::ICULine::GetLeading() const { - return 1.0f; + int leading = 0; + for (const auto &run : *this) { + leading = std::max(leading, run.GetLeading()); + } + + return leading; } -const void *Font::getFontTable(LETag tableTag) const +/** + * Get the width of this line. + * @return The width of the line. + */ +int ICUParagraphLayout::ICULine::GetWidth() const { - size_t length; - return this->getFontTable(tableTag, length); + int length = 0; + for (const auto &run : *this) { + length += run.GetAdvance(); + } + + return length; } -const void *Font::getFontTable(LETag tableTag, size_t &length) const +/** + * Itemize the string into runs per embedding level. + * + * Later on, based on the levels, we can deduce the order of a subset of runs. + * + * @param buff The string to itemize. + * @param length The length of the string. + * @return The runs. + */ +std::vector ItemizeBidi(UChar *buff, size_t length) { - return this->fc->GetFontTable(tableTag, length); + auto ubidi = ubidi_open(); + + auto parLevel = _current_text_dir == TD_RTL ? UBIDI_RTL : UBIDI_LTR; + + UErrorCode err = U_ZERO_ERROR; + ubidi_setPara(ubidi, buff, length, parLevel, nullptr, &err); + if (U_FAILURE(err)) { + Debug(fontcache, 0, "Failed to set paragraph: %s", u_errorName(err)); + ubidi_close(ubidi); + return std::vector(); + } + + int32_t count = ubidi_countRuns(ubidi, &err); + if (U_FAILURE(err)) { + Debug(fontcache, 0, "Failed to count runs: %s", u_errorName(err)); + ubidi_close(ubidi); + return std::vector(); + } + + std::vector runs; + runs.reserve(count); + + /* Find the breakpoints for the logical runs. So we get runs that say "from START to END". */ + int32_t logical_pos = 0; + while (static_cast(logical_pos) < length) { + auto start_pos = logical_pos; + + /* Fetch the embedding level, so we can order bidi correctly later on. */ + UBiDiLevel level; + ubidi_getLogicalRun(ubidi, start_pos, &logical_pos, &level); + + runs.emplace_back(ICURun(start_pos, logical_pos - start_pos, level)); + } + + assert(static_cast(count) == runs.size()); + + ubidi_close(ubidi); + return runs; } -LEGlyphID Font::mapCharToGlyph(LEUnicode32 ch) const +/** + * Itemize the string into runs per script, based on the previous created runs. + * + * Basically, this always returns the same or more runs than given. + * + * @param buff The string to itemize. + * @param length The length of the string. + * @param runs_current The current runs. + * @return The runs. + */ +std::vector ItemizeScript(UChar *buff, size_t length, std::vector &runs_current) { - if (IsTextDirectionChar(ch)) return 0; - return this->fc->MapCharToGlyph(ch); + std::vector runs; + icu::ScriptRun script_itemizer(buff, length); + + int cur_pos = 0; + auto cur_run = runs_current.begin(); + while (true) { + while (cur_pos < script_itemizer.getScriptEnd() && cur_run != runs_current.end()) { + int stop_pos = std::min(script_itemizer.getScriptEnd(), cur_run->start + cur_run->length); + assert(stop_pos - cur_pos > 0); + + runs.push_back(ICURun(cur_pos, stop_pos - cur_pos, cur_run->level, script_itemizer.getScriptCode())); + + if (stop_pos == cur_run->start + cur_run->length) cur_run++; + cur_pos = stop_pos; + } + + if (!script_itemizer.next()) break; + } + + return runs; } -void Font::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const +/** + * Itemize the string into runs per style, based on the previous created runs. + * + * Basically, this always returns the same or more runs than given. + * + * @param buff The string to itemize. + * @param length The length of the string. + * @param runs_current The current runs. + * @param font_mapping The font mapping. + * @return The runs. + */ +std::vector ItemizeStyle(UChar *buff, size_t length, std::vector &runs_current, FontMap &font_mapping) { - advance.fX = glyph == 0xFFFF ? 0 : this->fc->GetGlyphWidth(glyph); - advance.fY = 0; + std::vector runs; + + int cur_pos = 0; + auto cur_run = runs_current.begin(); + for (auto const &font_map : font_mapping) { + while (cur_pos < font_map.first && cur_run != runs_current.end()) { + int stop_pos = std::min(font_map.first, cur_run->start + cur_run->length); + assert(stop_pos - cur_pos > 0); + + runs.push_back(ICURun(cur_pos, stop_pos - cur_pos, cur_run->level, cur_run->script, font_map.second)); + + if (stop_pos == cur_run->start + cur_run->length) cur_run++; + cur_pos = stop_pos; + } + } + + return runs; } -le_bool Font::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const +/* static */ ParagraphLayouter *ICUParagraphLayoutFactory::GetParagraphLayout(UChar *buff, UChar *buff_end, FontMap &font_mapping) { - return false; + size_t length = buff_end - buff; + /* Can't layout an empty string. */ + if (length == 0) return nullptr; + + /* Can't layout our in-built sprite fonts. */ + for (auto const &pair : font_mapping) { + if (pair.second->fc->IsBuiltInFont()) return nullptr; + } + + auto runs = ItemizeBidi(buff, length); + runs = ItemizeScript(buff, length, runs); + runs = ItemizeStyle(buff, length, runs, font_mapping); + + if (runs.size() == 0) return nullptr; + + for (auto &run : runs) { + run.Shape(buff, length); + } + + return new ICUParagraphLayout(runs, buff, length); } -/** - * Wrapper for doing layouts with ICU. - */ -class ICUParagraphLayout : public ParagraphLayouter { - icu::ParagraphLayout *p; ///< The actual ICU paragraph layout. -public: - /** Visual run contains data about the bit of text with the same font. */ - class ICUVisualRun : public ParagraphLayouter::VisualRun { - const icu::ParagraphLayout::VisualRun *vr; ///< The actual ICU vr. +std::unique_ptr ICUParagraphLayout::NextLine(int max_width) +{ + std::vector::iterator start_run = this->current_run; + std::vector::iterator last_run = this->current_run; - public: - ICUVisualRun(const icu::ParagraphLayout::VisualRun *vr) : vr(vr) { } - - const Font *GetFont() const override { return (const Font*)vr->getFont(); } - int GetGlyphCount() const override { return vr->getGlyphCount(); } - const GlyphID *GetGlyphs() const override { return vr->getGlyphs(); } - const float *GetPositions() const override { return vr->getPositions(); } - int GetLeading() const override { return vr->getLeading(); } - const int *GetGlyphToCharMap() const override { return vr->getGlyphToCharMap(); } - }; + if (start_run == this->runs.end()) return nullptr; - /** A single line worth of VisualRuns. */ - class ICULine : public std::vector, public ParagraphLayouter::Line { - icu::ParagraphLayout::Line *l; ///< The actual ICU line. + int cur_width = 0; - public: - ICULine(icu::ParagraphLayout::Line *l) : l(l) - { - for (int i = 0; i < l->countRuns(); i++) { - this->emplace_back(l->getVisualRun(i)); + /* Add remaining width of the first run if it is a broken run. */ + if (this->partial_offset > 0) { + if ((start_run->level & 1) == 0) { + for (size_t i = this->partial_offset; i < start_run->advance.size(); i++) { + cur_width += start_run->advance[i]; + } + } else { + for (int i = 0; i < this->partial_offset; i++) { + cur_width += start_run->advance[i]; } } - ~ICULine() override { delete l; } + last_run++; + } - int GetLeading() const override { return l->getLeading(); } - int GetWidth() const override { return l->getWidth(); } - int CountRuns() const override { return l->countRuns(); } - const ParagraphLayouter::VisualRun &GetVisualRun(int run) const override { return this->at(run); } + /* Gather runs until the line is full. */ + while (last_run != this->runs.end() && cur_width < max_width) { + cur_width += last_run->total_advance; + last_run++; + } - int GetInternalCharLength(WChar c) const override - { - /* ICU uses UTF-16 internally which means we need to account for surrogate pairs. */ - return Utf8CharLen(c) < 4 ? 1 : 2; + /* If the text does not fit into the available width, find a suitable breaking point. */ + int new_partial_length = 0; + if (cur_width > max_width) { + auto locale = icu::Locale(_current_language->isocode); + + /* Create a break-iterator to find a good place to break lines. */ + UErrorCode err = U_ZERO_ERROR; + auto break_iterator = icu::BreakIterator::createLineInstance(locale, err); + break_iterator->setText(icu::UnicodeString(this->buff, this->buff_length)); + + auto overflow_run = last_run - 1; + + /* Find the last glyph that fits. */ + size_t index; + if ((overflow_run->level & 1) == 0) { + /* LTR */ + for (index = overflow_run->glyphs.size(); index > 0; index--) { + cur_width -= overflow_run->advance[index - 1]; + if (cur_width <= max_width) break; + } + index--; + } else { + /* RTL */ + for (index = 0; index < overflow_run->glyphs.size(); index++) { + cur_width -= overflow_run->advance[index]; + if (cur_width <= max_width) break; + } } - }; - ICUParagraphLayout(icu::ParagraphLayout *p) : p(p) { } - ~ICUParagraphLayout() override { delete p; } - void Reflow() override { p->reflow(); } + /* Find the character that matches; this is the start of the cluster. */ + auto char_pos = overflow_run->glyph_to_char[index]; + + /* See if there is a good breakpoint inside this run. */ + int32_t break_pos = break_iterator->preceding(char_pos + 1); + if (break_pos != icu::BreakIterator::DONE && break_pos > overflow_run->start + this->partial_offset) { + /* There is a line-break inside this run that is suitable. */ + new_partial_length = break_pos - overflow_run->start - this->partial_offset; + } else if (overflow_run != start_run) { + /* There is no suitable line-break in this run, but it is also not + * the only run on this line. So we remove the run. */ + last_run--; + } else { + /* There is no suitable line-break and this is the only run on the + * line. So we break at the cluster. This is not pretty, but the + * best we can do. */ + new_partial_length = char_pos - this->partial_offset; + } + } - std::unique_ptr NextLine(int max_width) override - { - icu::ParagraphLayout::Line *l = p->nextLine(max_width); - return std::unique_ptr(l == nullptr ? nullptr : new ICULine(l)); + /* Reorder the runs on this line for display. */ + std::vector bidi_level; + for (auto run = start_run; run != last_run; run++) { + bidi_level.push_back(run->level); } -}; + std::vector vis_to_log(bidi_level.size()); + ubidi_reorderVisual(bidi_level.data(), bidi_level.size(), vis_to_log.data()); + + /* Create line. */ + std::unique_ptr line(new ICULine()); + + int cur_pos = 0; + for (auto &i : vis_to_log) { + auto i_run = start_run + i; + /* Copy the ICURun here, so we can modify it in case of a partial. */ + ICURun run = *i_run; + + if (i_run == last_run - 1 && new_partial_length > 0) { + if (i_run == start_run && this->partial_offset > 0) { + assert(run.length > this->partial_offset); + run.start += this->partial_offset; + run.length -= this->partial_offset; + } -/* static */ ParagraphLayouter *ICUParagraphLayoutFactory::GetParagraphLayout(UChar *buff, UChar *buff_end, FontMap &fontMapping) -{ - int32 length = buff_end - buff; + assert(run.length > new_partial_length); + run.length = new_partial_length; - if (length == 0) { - /* ICU's ParagraphLayout cannot handle empty strings, so fake one. */ - buff[0] = ' '; - length = 1; - fontMapping.back().first++; - } + run.Shape(this->buff, this->buff_length); + } else if (i_run == start_run && this->partial_offset > 0) { + assert(run.length > this->partial_offset); + + run.start += this->partial_offset; + run.length -= this->partial_offset; + + run.Shape(this->buff, this->buff_length); + } - /* Fill ICU's FontRuns with the right data. */ - icu::FontRuns runs(fontMapping.size()); - for (auto &pair : fontMapping) { - runs.add(pair.second, pair.first); + auto total_advance = run.total_advance; + line->emplace_back(std::move(run), cur_pos); + cur_pos += total_advance; } - LEErrorCode status = LE_NO_ERROR; - /* ParagraphLayout does not copy "buff", so it must stay valid. - * "runs" is copied according to the ICU source, but the documentation does not specify anything, so this might break somewhen. */ - icu::ParagraphLayout *p = new icu::ParagraphLayout(buff, length, &runs, nullptr, nullptr, nullptr, _current_text_dir == TD_RTL ? 1 : 0, false, status); - if (status != LE_NO_ERROR) { - delete p; - return nullptr; + if (new_partial_length > 0) { + this->current_run = last_run - 1; + this->partial_offset += new_partial_length; + } else { + this->current_run = last_run; + this->partial_offset = 0; } - return new ICUParagraphLayout(p); + return line; } /* static */ size_t ICUParagraphLayoutFactory::AppendToBuffer(UChar *buff, const UChar *buffer_last, WChar c) diff --git a/src/gfx_layout_icu.h b/src/gfx_layout_icu.h index cdebcbc0b4..2aff3cb555 100644 --- a/src/gfx_layout_icu.h +++ b/src/gfx_layout_icu.h @@ -11,6 +11,7 @@ #define GFX_LAYOUT_ICU_H #include "gfx_layout.h" + #include /** diff --git a/src/strings.cpp b/src/strings.cpp index 0e885e7387..5b88f3444d 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -2252,7 +2252,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) /* Update the font with cache */ LoadStringWidthTable(searcher->Monospace()); -#if !defined(WITH_ICU_LX) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA) +#if !(defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA) /* * For right-to-left languages we need the ICU library. If * we do not have support for that library we warn the user @@ -2267,10 +2267,10 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) * the colour marker. */ if (_current_text_dir != TD_LTR) { - static std::string err_str("XXXThis version of OpenTTD does not support right-to-left languages. Recompile with icu enabled."); + static std::string err_str("XXXThis version of OpenTTD does not support right-to-left languages. Recompile with ICU + Harfbuzz enabled."); Utf8Encode(err_str.data(), SCC_YELLOW); SetDParamStr(0, err_str); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); } -#endif /* !WITH_ICU_LX */ +#endif /* !(WITH_ICU_I18N && WITH_HARFBUZZ) && !WITH_UNISCRIBE && !WITH_COCOA */ } From 47a8d12f0e8ebc3ce0ea3f7f5fad928d5f29be4b Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 2 May 2023 18:39:14 +0000 Subject: [PATCH 05/34] Update: Translations from eints english (au): 14 changes by krysclarke korean: 14 changes by telk5093 italian: 14 changes by Rivarossi russian: 15 changes by Ln-Wolf finnish: 14 changes by hpiirai turkish: 14 changes by densxd portuguese: 16 changes by azulcosta --- src/lang/english_AU.txt | 18 ++++++++++++++++-- src/lang/finnish.txt | 18 ++++++++++++++++-- src/lang/italian.txt | 18 ++++++++++++++++-- src/lang/korean.txt | 18 ++++++++++++++++-- src/lang/portuguese.txt | 22 ++++++++++++++++++---- src/lang/russian.txt | 22 ++++++++++++++++++---- src/lang/turkish.txt | 18 ++++++++++++++++-- 7 files changed, 116 insertions(+), 18 deletions(-) diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index dee9ad8a88..bc95ab563b 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -931,8 +931,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Paste th # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Game Options - - +STR_GAME_OPTIONS_TAB_GENERAL :General +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Choose general settings +STR_GAME_OPTIONS_TAB_GRAPHICS :Graphics +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Choose graphics settings +STR_GAME_OPTIONS_TAB_SOUND :Sound +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Choose sound and music settings + +STR_GAME_OPTIONS_VOLUME :Volume +STR_GAME_OPTIONS_SFX_VOLUME :Sound effects +STR_GAME_OPTIONS_MUSIC_VOLUME :Music + +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Currency units STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Currency units selection diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index bc5ace71c4..b04e942303 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -931,8 +931,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Siirrä # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Pelin valinnat - - +STR_GAME_OPTIONS_TAB_GENERAL :Yleiset +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Valitse yleisasetukset +STR_GAME_OPTIONS_TAB_GRAPHICS :Grafiikka +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Valitse grafiikka-asetukset +STR_GAME_OPTIONS_TAB_SOUND :Ääni +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Valitse ääni- ja musiikkiasetukset + +STR_GAME_OPTIONS_VOLUME :Äänenvoimakkuus +STR_GAME_OPTIONS_SFX_VOLUME :Äänitehosteet +STR_GAME_OPTIONS_MUSIC_VOLUME :Musiikki + +STR_GAME_OPTIONS_VOLUME_0 :0{NBSP}% +STR_GAME_OPTIONS_VOLUME_25 :25{NBSP}% +STR_GAME_OPTIONS_VOLUME_50 :50{NBSP}% +STR_GAME_OPTIONS_VOLUME_75 :75{NBSP}% +STR_GAME_OPTIONS_VOLUME_100 :100{NBSP}% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Rahayksikkö STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Rahayksikön valinta diff --git a/src/lang/italian.txt b/src/lang/italian.txt index 30784f4705..b6f4ac01b0 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -933,8 +933,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia la # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opzioni di gioco - - +STR_GAME_OPTIONS_TAB_GENERAL :Generale +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Scegliere le impostazioni generali +STR_GAME_OPTIONS_TAB_GRAPHICS :Grafica +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Scegliere le impostazioni grafiche +STR_GAME_OPTIONS_TAB_SOUND :Suono +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Scegliere le impostazioni audio e musicali + +STR_GAME_OPTIONS_VOLUME :Volume +STR_GAME_OPTIONS_SFX_VOLUME :Effetti sonori +STR_GAME_OPTIONS_MUSIC_VOLUME :Musica + +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valuta STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selezione della valuta diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 597659cc83..b77b15c662 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -932,8 +932,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}외부 # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}게임 기본 설정 - - +STR_GAME_OPTIONS_TAB_GENERAL :일반 +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}일반 설정을 선택합니다 +STR_GAME_OPTIONS_TAB_GRAPHICS :그래픽 +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}그래픽 설정을 선택합니다 +STR_GAME_OPTIONS_TAB_SOUND :효과음 +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}효과음과 배경음 설정을 선택합니다 + +STR_GAME_OPTIONS_VOLUME :음량 +STR_GAME_OPTIONS_SFX_VOLUME :효과음 +STR_GAME_OPTIONS_MUSIC_VOLUME :배경음 + +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}화폐 단위 STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}화폐 단위 선택 diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index de27d357fd..63d43f8f32 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -932,8 +932,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copiar a # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opções do Jogo - - +STR_GAME_OPTIONS_TAB_GENERAL :Geral +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Escolher definições gerais +STR_GAME_OPTIONS_TAB_GRAPHICS :Gráficos +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Escolher definições gráficas +STR_GAME_OPTIONS_TAB_SOUND :Som +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Escolher definições de sons e música + +STR_GAME_OPTIONS_VOLUME :Volume +STR_GAME_OPTIONS_SFX_VOLUME :Efeitos sonoros +STR_GAME_OPTIONS_MUSIC_VOLUME :Música + +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Unidades monetárias STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selecção de unidades monetárias @@ -1389,8 +1403,8 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Não é STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Manutenção de infraestruturas: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Quando ativo, as infraestruturas têm custos de manutenção. O custo cresce mais do que proporcionalmente com o tamanho da rede e com isso afeta mais as companhias maiores comparando com as mais pequenas -STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Côr de inicio da empresa: {STRING} -STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Escolher côr de inicio da empresa +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Cor inicial da empresa: {STRING} +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Escolher a cor inicial da empresa STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Aeroportos nunca expiram: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Ativar esta preferência torna cada tipo de aeroporto disponível para sempre após a sua introdução diff --git a/src/lang/russian.txt b/src/lang/russian.txt index cdbbb10659..88eb16f643 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -1074,10 +1074,24 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}В ос STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Показать в основном окне # Game options window -STR_GAME_OPTIONS_CAPTION :{WHITE}Основные настройки - - - +STR_GAME_OPTIONS_CAPTION :{WHITE}Настройки + +STR_GAME_OPTIONS_TAB_GENERAL :Основные +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Основные настройки игры +STR_GAME_OPTIONS_TAB_GRAPHICS :Графика +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Настройки графики +STR_GAME_OPTIONS_TAB_SOUND :Звук +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Настройки звука и музыки + +STR_GAME_OPTIONS_VOLUME :Громкость +STR_GAME_OPTIONS_SFX_VOLUME :Звуковые эффекты +STR_GAME_OPTIONS_MUSIC_VOLUME :Музыка + +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Валюта STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Смена используемой в игре валюты diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index e2f5680b30..5af62ef30e 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -932,8 +932,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Bu gör # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Seçenekler - - +STR_GAME_OPTIONS_TAB_GENERAL :Genel +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Genel ayarları seçin +STR_GAME_OPTIONS_TAB_GRAPHICS :Grafikler +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Grafik ayarlarını seçin +STR_GAME_OPTIONS_TAB_SOUND :Ses +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Ses ve müzik ayarlarını seçin + +STR_GAME_OPTIONS_VOLUME :Ses seviyesi +STR_GAME_OPTIONS_SFX_VOLUME :Ses efektleri +STR_GAME_OPTIONS_MUSIC_VOLUME :Müzik + +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Para birimleri STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Para birimi seçimi From 00bf42353a4ee539060c9f95a555e50b0b7c542d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 1 May 2023 18:14:31 +0100 Subject: [PATCH 06/34] Codechange: Place gamelog into its own class, along with internal data. Data is now stored in vectors to avoid manual memory management and passing lengths around. --- src/console_cmds.cpp | 2 +- src/crashlog.cpp | 4 +- src/fios.h | 15 +- src/fios_gui.cpp | 6 +- src/gamelog.cpp | 362 +++++++++++++++----------------- src/gamelog.h | 87 ++++++-- src/gamelog_internal.h | 28 +-- src/misc.cpp | 12 +- src/newgrf_gui.cpp | 6 +- src/openttd.cpp | 4 +- src/os/macosx/crashlog_osx.cpp | 2 +- src/os/unix/crashlog_unix.cpp | 2 +- src/os/windows/crashlog_win.cpp | 2 +- src/saveload/afterload.cpp | 34 +-- src/saveload/gamelog_sl.cpp | 63 ++---- src/saveload/saveload.cpp | 18 +- src/settings.cpp | 6 +- src/vehicle.cpp | 2 +- 18 files changed, 309 insertions(+), 346 deletions(-) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 5a3345d512..eb6bb0cbd1 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -2116,7 +2116,7 @@ DEF_CONSOLE_CMD(ConListSettings) DEF_CONSOLE_CMD(ConGamelogPrint) { - GamelogPrintConsole(); + _gamelog.PrintConsole(); return true; } diff --git a/src/crashlog.cpp b/src/crashlog.cpp index d1bf8cfd54..9dda4d0b26 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -301,7 +301,7 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const */ char *CrashLog::LogGamelog(char *buffer, const char *last) const { - GamelogPrint([&buffer, last](const char *s) { + _gamelog.Print([&buffer, last](const char *s) { buffer += seprintf(buffer, last, "%s\n", s); }); return buffer + seprintf(buffer, last, "\n"); @@ -423,7 +423,7 @@ bool CrashLog::WriteSavegame(char *filename, const char *filename_last) const if (!Map::IsInitialized()) return false; try { - GamelogEmergency(); + _gamelog.Emergency(); this->CreateFileName(filename, filename_last, ".sav"); diff --git a/src/fios.h b/src/fios.h index d5e0b9ff7a..bb850e05a9 100644 --- a/src/fios.h +++ b/src/fios.h @@ -13,6 +13,7 @@ #include "gfx_type.h" #include "company_base.h" #include "newgrf_config.h" +#include "gamelog.h" #include "network/core/tcp_content_type.h" #include "timer/timer_game_calendar.h" @@ -44,21 +45,11 @@ struct LoadCheckData { GRFConfig *grfconfig; ///< NewGrf configuration from save. GRFListCompatibility grf_compatibility; ///< Summary state of NewGrfs, whether missing files or only compatible found. - struct LoggedAction *gamelog_action; ///< Gamelog actions - uint gamelog_actions; ///< Number of gamelog actions + Gamelog gamelog; ///< Gamelog actions LoadCheckData() : grfconfig(nullptr), - grf_compatibility(GLC_NOT_FOUND), gamelog_action(nullptr), gamelog_actions(0) + grf_compatibility(GLC_NOT_FOUND) { - this->Clear(); - } - - /** - * Don't leak memory at program exit - */ - ~LoadCheckData() - { - this->Clear(); } /** diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index c358e4a597..1f2f8e5b8c 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -28,6 +28,7 @@ #include "gamelog.h" #include "stringfilter_type.h" #include "misc_cmd.h" +#include "gamelog_internal.h" #include "widgets/fios_widget.h" @@ -41,7 +42,6 @@ LoadCheckData _load_check_data; ///< Data loaded from save during SL_LOAD_CHE static bool _fios_path_changed; static bool _savegame_sort_dirty; - /** * Reset read data. */ @@ -60,9 +60,7 @@ void LoadCheckData::Clear() } companies.clear(); - GamelogFree(this->gamelog_action, this->gamelog_actions); - this->gamelog_action = nullptr; - this->gamelog_actions = 0; + this->gamelog.Reset(); ClearGRFConfigList(&this->grfconfig); } diff --git a/src/gamelog.cpp b/src/gamelog.cpp index 84013e205a..e3b69f081f 100644 --- a/src/gamelog.cpp +++ b/src/gamelog.cpp @@ -30,13 +30,23 @@ extern uint32 _ttdp_version; ///< version of TTDP savegame (if applicable extern SaveLoadVersion _sl_version; ///< the major savegame version identifier extern byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! +Gamelog _gamelog; ///< Gamelog instance -static GamelogActionType _gamelog_action_type = GLAT_NONE; ///< action to record if anything changes +LoggedChange::~LoggedChange() +{ + if (this->ct == GLCT_SETTING) free(this->setting.name); +} -LoggedAction *_gamelog_action = nullptr; ///< first logged action -uint _gamelog_actions = 0; ///< number of actions -static LoggedAction *_current_action = nullptr; ///< current action we are logging, nullptr when there is no action active +Gamelog::Gamelog() +{ + this->data = std::make_unique(); + this->action_type = GLAT_NONE; + this->current_action = nullptr; +} +Gamelog::~Gamelog() +{ +} /** * Return the revision string for the current client version, for use in gamelog. @@ -67,60 +77,40 @@ static const char * GetGamelogRevisionString() * Action is allocated only when there is at least one change * @param at type of action */ -void GamelogStartAction(GamelogActionType at) +void Gamelog::StartAction(GamelogActionType at) { - assert(_gamelog_action_type == GLAT_NONE); // do not allow starting new action without stopping the previous first - _gamelog_action_type = at; + assert(this->action_type == GLAT_NONE); // do not allow starting new action without stopping the previous first + this->action_type = at; } /** * Stops logging of any changes */ -void GamelogStopAction() +void Gamelog::StopAction() { - assert(_gamelog_action_type != GLAT_NONE); // nobody should try to stop if there is no action in progress + assert(this->action_type != GLAT_NONE); // nobody should try to stop if there is no action in progress - bool print = _current_action != nullptr; + bool print = this->current_action != nullptr; - _current_action = nullptr; - _gamelog_action_type = GLAT_NONE; + this->current_action = nullptr; + this->action_type = GLAT_NONE; - if (print) GamelogPrintDebug(5); + if (print) this->PrintDebug(5); } -void GamelogStopAnyAction() +void Gamelog::StopAnyAction() { - if (_gamelog_action_type != GLAT_NONE) GamelogStopAction(); -} - -/** - * Frees the memory allocated by a gamelog - */ -void GamelogFree(LoggedAction *gamelog_action, uint gamelog_actions) -{ - for (uint i = 0; i < gamelog_actions; i++) { - const LoggedAction *la = &gamelog_action[i]; - for (uint j = 0; j < la->changes; j++) { - const LoggedChange *lc = &la->change[j]; - if (lc->ct == GLCT_SETTING) free(lc->setting.name); - } - free(la->change); - } - - free(gamelog_action); + if (this->action_type != GLAT_NONE) this->StopAction(); } /** * Resets and frees all memory allocated - used before loading or starting a new game */ -void GamelogReset() +void Gamelog::Reset() { - assert(_gamelog_action_type == GLAT_NONE); - GamelogFree(_gamelog_action, _gamelog_actions); - - _gamelog_action = nullptr; - _gamelog_actions = 0; - _current_action = nullptr; + assert(this->action_type == GLAT_NONE); + this->data->action.clear(); + this->current_action = nullptr; } /** @@ -190,56 +180,52 @@ typedef SmallMap GrfIDMapping; * Prints active gamelog * @param proc the procedure to draw with */ -void GamelogPrint(std::function proc) +void Gamelog::Print(std::function proc) { char buffer[1024]; GrfIDMapping grf_names; proc("---- gamelog start ----"); - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; + for (const LoggedAction &la : this->data->action) { + assert((uint)la.at < GLAT_END); - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - assert((uint)la->at < GLAT_END); - - seprintf(buffer, lastof(buffer), "Tick %u: %s", (uint)la->tick, la_text[(uint)la->at]); + seprintf(buffer, lastof(buffer), "Tick %u: %s", (uint)la.tick, la_text[(uint)la.at]); proc(buffer); - const LoggedChange *lcend = &la->change[la->changes]; - - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { + for (const LoggedChange &lc : la.change) { char *buf = buffer; - switch (lc->ct) { + switch (lc.ct) { default: NOT_REACHED(); case GLCT_MODE: /* Changing landscape, or going from scenario editor to game or back. */ buf += seprintf(buf, lastof(buffer), "New game mode: %u landscape: %u", - (uint)lc->mode.mode, (uint)lc->mode.landscape); + (uint)lc.mode.mode, (uint)lc.mode.landscape); break; case GLCT_REVISION: /* The game was loaded in a diffferent version than before. */ buf += seprintf(buf, lastof(buffer), "Revision text changed to %s, savegame version %u, ", - lc->revision.text, lc->revision.slver); + lc.revision.text, lc.revision.slver); - switch (lc->revision.modified) { + switch (lc.revision.modified) { case 0: buf += seprintf(buf, lastof(buffer), "not "); break; case 1: buf += seprintf(buf, lastof(buffer), "maybe "); break; default: break; } - buf += seprintf(buf, lastof(buffer), "modified, _openttd_newgrf_version = 0x%08x", lc->revision.newgrf); + buf += seprintf(buf, lastof(buffer), "modified, _openttd_newgrf_version = 0x%08x", lc.revision.newgrf); break; case GLCT_OLDVER: /* The game was loaded from before 0.7.0-beta1. */ buf += seprintf(buf, lastof(buffer), "Conversion from "); - switch (lc->oldver.type) { + switch (lc.oldver.type) { default: NOT_REACHED(); case SGT_OTTD: buf += seprintf(buf, lastof(buffer), "OTTD savegame without gamelog: version %u, %u", - GB(lc->oldver.version, 8, 16), GB(lc->oldver.version, 0, 8)); + GB(lc.oldver.version, 8, 16), GB(lc.oldver.version, 0, 8)); break; case SGT_TTO: @@ -253,11 +239,11 @@ void GamelogPrint(std::function proc) case SGT_TTDP1: case SGT_TTDP2: buf += seprintf(buf, lastof(buffer), "TTDP savegame, %s format", - lc->oldver.type == SGT_TTDP1 ? "old" : "new"); - if (lc->oldver.version != 0) { + lc.oldver.type == SGT_TTDP1 ? "old" : "new"); + if (lc.oldver.version != 0) { buf += seprintf(buf, lastof(buffer), ", TTDP version %u.%u.%u.%u", - GB(lc->oldver.version, 24, 8), GB(lc->oldver.version, 20, 4), - GB(lc->oldver.version, 16, 4), GB(lc->oldver.version, 0, 16)); + GB(lc.oldver.version, 24, 8), GB(lc.oldver.version, 20, 4), + GB(lc.oldver.version, 16, 4), GB(lc.oldver.version, 0, 16)); } break; } @@ -265,29 +251,29 @@ void GamelogPrint(std::function proc) case GLCT_SETTING: /* A setting with the SF_NO_NETWORK flag got changed; these settings usually affect NewGRFs, such as road side or wagon speed limits. */ - buf += seprintf(buf, lastof(buffer), "Setting changed: %s : %d -> %d", lc->setting.name, lc->setting.oldval, lc->setting.newval); + buf += seprintf(buf, lastof(buffer), "Setting changed: %s : %d -> %d", lc.setting.name, lc.setting.oldval, lc.setting.newval); break; case GLCT_GRFADD: { /* A NewGRF got added to the game, either at the start of the game (never an issue), or later on when it could be an issue. */ - const GRFConfig *gc = FindGRFConfig(lc->grfadd.grfid, FGCM_EXACT, lc->grfadd.md5sum); + const GRFConfig *gc = FindGRFConfig(lc.grfadd.grfid, FGCM_EXACT, lc.grfadd.md5sum); buf += seprintf(buf, lastof(buffer), "Added NewGRF: "); - buf = PrintGrfInfo(buf, lastof(buffer), lc->grfadd.grfid, lc->grfadd.md5sum, gc); - GrfIDMapping::Pair *gm = grf_names.Find(lc->grfrem.grfid); + buf = PrintGrfInfo(buf, lastof(buffer), lc.grfadd.grfid, lc.grfadd.md5sum, gc); + GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); if (gm != grf_names.End() && !gm->second.was_missing) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was already added!"); - grf_names[lc->grfadd.grfid] = gc; + grf_names[lc.grfadd.grfid] = gc; break; } case GLCT_GRFREM: { /* A NewGRF got removed from the game, either manually or by it missing when loading the game. */ - GrfIDMapping::Pair *gm = grf_names.Find(lc->grfrem.grfid); - buf += seprintf(buf, lastof(buffer), la->at == GLAT_LOAD ? "Missing NewGRF: " : "Removed NewGRF: "); - buf = PrintGrfInfo(buf, lastof(buffer), lc->grfrem.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); + GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); + buf += seprintf(buf, lastof(buffer), la.at == GLAT_LOAD ? "Missing NewGRF: " : "Removed NewGRF: "); + buf = PrintGrfInfo(buf, lastof(buffer), lc.grfrem.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); if (gm == grf_names.End()) { buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); } else { - if (la->at == GLAT_LOAD) { + if (la.at == GLAT_LOAD) { /* Missing grfs on load are not removed from the configuration */ gm->second.was_missing = true; } else { @@ -299,40 +285,40 @@ void GamelogPrint(std::function proc) case GLCT_GRFCOMPAT: { /* Another version of the same NewGRF got loaded. */ - const GRFConfig *gc = FindGRFConfig(lc->grfadd.grfid, FGCM_EXACT, lc->grfadd.md5sum); + const GRFConfig *gc = FindGRFConfig(lc.grfadd.grfid, FGCM_EXACT, lc.grfadd.md5sum); buf += seprintf(buf, lastof(buffer), "Compatible NewGRF loaded: "); - buf = PrintGrfInfo(buf, lastof(buffer), lc->grfcompat.grfid, lc->grfcompat.md5sum, gc); - if (!grf_names.Contains(lc->grfcompat.grfid)) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); - grf_names[lc->grfcompat.grfid] = gc; + buf = PrintGrfInfo(buf, lastof(buffer), lc.grfcompat.grfid, lc.grfcompat.md5sum, gc); + if (!grf_names.Contains(lc.grfcompat.grfid)) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); + grf_names[lc.grfcompat.grfid] = gc; break; } case GLCT_GRFPARAM: { /* A parameter of a NewGRF got changed after the game was started. */ - GrfIDMapping::Pair *gm = grf_names.Find(lc->grfrem.grfid); + GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); buf += seprintf(buf, lastof(buffer), "GRF parameter changed: "); - buf = PrintGrfInfo(buf, lastof(buffer), lc->grfparam.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); + buf = PrintGrfInfo(buf, lastof(buffer), lc.grfparam.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); if (gm == grf_names.End()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); break; } case GLCT_GRFMOVE: { /* The order of NewGRFs got changed, which might cause some other NewGRFs to behave differently. */ - GrfIDMapping::Pair *gm = grf_names.Find(lc->grfrem.grfid); + GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); buf += seprintf(buf, lastof(buffer), "GRF order changed: %08X moved %d places %s", - BSWAP32(lc->grfmove.grfid), abs(lc->grfmove.offset), lc->grfmove.offset >= 0 ? "down" : "up" ); - buf = PrintGrfInfo(buf, lastof(buffer), lc->grfmove.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); + BSWAP32(lc.grfmove.grfid), abs(lc.grfmove.offset), lc.grfmove.offset >= 0 ? "down" : "up" ); + buf = PrintGrfInfo(buf, lastof(buffer), lc.grfmove.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); if (gm == grf_names.End()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); break; } case GLCT_GRFBUG: { /* A specific bug in a NewGRF, that could cause wide spread problems, has been noted during the execution of the game. */ - GrfIDMapping::Pair *gm = grf_names.Find(lc->grfrem.grfid); - assert (lc->grfbug.bug == GBUG_VEH_LENGTH); + GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); + assert(lc.grfbug.bug == GBUG_VEH_LENGTH); - buf += seprintf(buf, lastof(buffer), "Rail vehicle changes length outside a depot: GRF ID %08X, internal ID 0x%X", BSWAP32(lc->grfbug.grfid), (uint)lc->grfbug.data); - buf = PrintGrfInfo(buf, lastof(buffer), lc->grfbug.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); + buf += seprintf(buf, lastof(buffer), "Rail vehicle changes length outside a depot: GRF ID %08X, internal ID 0x%X", BSWAP32(lc.grfbug.grfid), (uint)lc.grfbug.data); + buf = PrintGrfInfo(buf, lastof(buffer), lc.grfbug.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); if (gm == grf_names.End()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); break; } @@ -352,9 +338,9 @@ void GamelogPrint(std::function proc) /** Print the gamelog data to the console. */ -void GamelogPrintConsole() +void Gamelog::PrintConsole() { - GamelogPrint([](const char *s) { + this->Print([](const char *s) { IConsolePrint(CC_WARNING, s); }); } @@ -365,9 +351,9 @@ void GamelogPrintConsole() * doesn't matter that much. At least it gives more uniform code... * @param level debug level we need to print stuff */ -void GamelogPrintDebug(int level) +void Gamelog::PrintDebug(int level) { - GamelogPrint([level](const char *s) { + this->Print([level](const char *s) { Debug(gamelog, level, "{}", s); }); } @@ -379,23 +365,17 @@ void GamelogPrintDebug(int level) * @param ct type of change * @return new LoggedChange, or nullptr if there is no action active */ -static LoggedChange *GamelogChange(GamelogChangeType ct) +LoggedChange *Gamelog::Change(GamelogChangeType ct) { - if (_current_action == nullptr) { - if (_gamelog_action_type == GLAT_NONE) return nullptr; + if (this->current_action == nullptr) { + if (this->action_type == GLAT_NONE) return nullptr; - _gamelog_action = ReallocT(_gamelog_action, _gamelog_actions + 1); - _current_action = &_gamelog_action[_gamelog_actions++]; - - _current_action->at = _gamelog_action_type; - _current_action->tick = TimerGameTick::counter; - _current_action->change = nullptr; - _current_action->changes = 0; + this->current_action = &this->data->action.emplace_back(); + this->current_action->at = this->action_type; + this->current_action->tick = TimerGameTick::counter; } - _current_action->change = ReallocT(_current_action->change, _current_action->changes + 1); - - LoggedChange *lc = &_current_action->change[_current_action->changes++]; + LoggedChange *lc = &this->current_action->change.emplace_back(); lc->ct = ct; return lc; @@ -405,41 +385,37 @@ static LoggedChange *GamelogChange(GamelogChangeType ct) /** * Logs a emergency savegame */ -void GamelogEmergency() +void Gamelog::Emergency() { /* Terminate any active action */ - if (_gamelog_action_type != GLAT_NONE) GamelogStopAction(); - GamelogStartAction(GLAT_EMERGENCY); - GamelogChange(GLCT_EMERGENCY); - GamelogStopAction(); + if (this->action_type != GLAT_NONE) this->StopAction(); + this->StartAction(GLAT_EMERGENCY); + this->Change(GLCT_EMERGENCY); + this->StopAction(); } /** * Finds out if current game is a loaded emergency savegame. */ -bool GamelogTestEmergency() +bool Gamelog::TestEmergency() { - const LoggedChange *emergency = nullptr; - - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_EMERGENCY) emergency = lc; + for (const LoggedAction &la : this->data->action) { + for (const LoggedChange &lc : la.change) { + if (lc.ct == GLCT_EMERGENCY) return true; } } - return (emergency != nullptr); + return false; } /** * Logs a change in game revision */ -void GamelogRevision() +void Gamelog::Revision() { - assert(_gamelog_action_type == GLAT_START || _gamelog_action_type == GLAT_LOAD); + assert(this->action_type == GLAT_START || this->action_type == GLAT_LOAD); - LoggedChange *lc = GamelogChange(GLCT_REVISION); + LoggedChange *lc = this->Change(GLCT_REVISION); if (lc == nullptr) return; memset(lc->revision.text, 0, sizeof(lc->revision.text)); @@ -452,11 +428,11 @@ void GamelogRevision() /** * Logs a change in game mode (scenario editor or game) */ -void GamelogMode() +void Gamelog::Mode() { - assert(_gamelog_action_type == GLAT_START || _gamelog_action_type == GLAT_LOAD || _gamelog_action_type == GLAT_CHEAT); + assert(this->action_type == GLAT_START || this->action_type == GLAT_LOAD || this->action_type == GLAT_CHEAT); - LoggedChange *lc = GamelogChange(GLCT_MODE); + LoggedChange *lc = this->Change(GLCT_MODE); if (lc == nullptr) return; lc->mode.mode = _game_mode; @@ -466,11 +442,11 @@ void GamelogMode() /** * Logs loading from savegame without gamelog */ -void GamelogOldver() +void Gamelog::Oldver() { - assert(_gamelog_action_type == GLAT_LOAD); + assert(this->action_type == GLAT_LOAD); - LoggedChange *lc = GamelogChange(GLCT_OLDVER); + LoggedChange *lc = this->Change(GLCT_OLDVER); if (lc == nullptr) return; lc->oldver.type = _savegame_type; @@ -483,11 +459,11 @@ void GamelogOldver() * @param oldval old setting value * @param newval new setting value */ -void GamelogSetting(const std::string &name, int32 oldval, int32 newval) +void Gamelog::Setting(const std::string &name, int32 oldval, int32 newval) { - assert(_gamelog_action_type == GLAT_SETTING); + assert(this->action_type == GLAT_SETTING); - LoggedChange *lc = GamelogChange(GLCT_SETTING); + LoggedChange *lc = this->Change(GLCT_SETTING); if (lc == nullptr) return; lc->setting.name = stredup(name.c_str()); @@ -500,22 +476,20 @@ void GamelogSetting(const std::string &name, int32 oldval, int32 newval) * Finds out if current revision is different than last revision stored in the savegame. * Appends GLCT_REVISION when the revision string changed */ -void GamelogTestRevision() +void Gamelog::TestRevision() { const LoggedChange *rev = nullptr; - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_REVISION) rev = lc; + for (const LoggedAction &la : this->data->action) { + for (const LoggedChange &lc : la.change) { + if (lc.ct == GLCT_REVISION) rev = &lc; } } if (rev == nullptr || strcmp(rev->revision.text, GetGamelogRevisionString()) != 0 || rev->revision.modified != _openttd_revision_modified || rev->revision.newgrf != _openttd_newgrf_version) { - GamelogRevision(); + this->Revision(); } } @@ -523,19 +497,17 @@ void GamelogTestRevision() * Finds last stored game mode or landscape. * Any change is logged */ -void GamelogTestMode() +void Gamelog::TestMode() { const LoggedChange *mode = nullptr; - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_MODE) mode = lc; + for (const LoggedAction &la : this->data->action) { + for (const LoggedChange &lc : la.change) { + if (lc.ct == GLCT_MODE) mode = &lc; } } - if (mode == nullptr || mode->mode.mode != _game_mode || mode->mode.landscape != _settings_game.game_creation.landscape) GamelogMode(); + if (mode == nullptr || mode->mode.mode != _game_mode || mode->mode.landscape != _settings_game.game_creation.landscape) this->Mode(); } @@ -545,11 +517,11 @@ void GamelogTestMode() * @param bug type of bug, @see enum GRFBugs * @param data additional data */ -static void GamelogGRFBug(uint32 grfid, byte bug, uint64 data) +void Gamelog::GRFBug(uint32 grfid, byte bug, uint64 data) { - assert(_gamelog_action_type == GLAT_GRFBUG); + assert(this->action_type == GLAT_GRFBUG); - LoggedChange *lc = GamelogChange(GLCT_GRFBUG); + LoggedChange *lc = this->Change(GLCT_GRFBUG); if (lc == nullptr) return; lc->grfbug.data = data; @@ -566,22 +538,20 @@ static void GamelogGRFBug(uint32 grfid, byte bug, uint64 data) * @param internal_id the internal ID of whatever's broken in the NewGRF * @return true iff a unique record was done */ -bool GamelogGRFBugReverse(uint32 grfid, uint16 internal_id) -{ - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_GRFBUG && lc->grfbug.grfid == grfid && - lc->grfbug.bug == GBUG_VEH_LENGTH && lc->grfbug.data == internal_id) { +bool Gamelog::GRFBugReverse(uint32 grfid, uint16 internal_id) +{ + for (const LoggedAction &la : this->data->action) { + for (const LoggedChange &lc : la.change) { + if (lc.ct == GLCT_GRFBUG && lc.grfbug.grfid == grfid && + lc.grfbug.bug == GBUG_VEH_LENGTH && lc.grfbug.data == internal_id) { return false; } } } - GamelogStartAction(GLAT_GRFBUG); - GamelogGRFBug(grfid, GBUG_VEH_LENGTH, internal_id); - GamelogStopAction(); + this->StartAction(GLAT_GRFBUG); + this->GRFBug(grfid, GBUG_VEH_LENGTH, internal_id); + this->StopAction(); return true; } @@ -601,11 +571,11 @@ static inline bool IsLoggableGrfConfig(const GRFConfig *g) * Logs removal of a GRF * @param grfid ID of removed GRF */ -void GamelogGRFRemove(uint32 grfid) +void Gamelog::GRFRemove(uint32 grfid) { - assert(_gamelog_action_type == GLAT_LOAD || _gamelog_action_type == GLAT_GRF); + assert(this->action_type == GLAT_LOAD || this->action_type == GLAT_GRF); - LoggedChange *lc = GamelogChange(GLCT_GRFREM); + LoggedChange *lc = this->Change(GLCT_GRFREM); if (lc == nullptr) return; lc->grfrem.grfid = grfid; @@ -615,13 +585,13 @@ void GamelogGRFRemove(uint32 grfid) * Logs adding of a GRF * @param newg added GRF */ -void GamelogGRFAdd(const GRFConfig *newg) +void Gamelog::GRFAdd(const GRFConfig *newg) { - assert(_gamelog_action_type == GLAT_LOAD || _gamelog_action_type == GLAT_START || _gamelog_action_type == GLAT_GRF); + assert(this->action_type == GLAT_LOAD || this->action_type == GLAT_START || this->action_type == GLAT_GRF); if (!IsLoggableGrfConfig(newg)) return; - LoggedChange *lc = GamelogChange(GLCT_GRFADD); + LoggedChange *lc = this->Change(GLCT_GRFADD); if (lc == nullptr) return; lc->grfadd = newg->ident; @@ -632,11 +602,11 @@ void GamelogGRFAdd(const GRFConfig *newg) * (the same ID, but different MD5 hash) * @param newg new (updated) GRF */ -void GamelogGRFCompatible(const GRFIdentifier *newg) +void Gamelog::GRFCompatible(const GRFIdentifier *newg) { - assert(_gamelog_action_type == GLAT_LOAD || _gamelog_action_type == GLAT_GRF); + assert(this->action_type == GLAT_LOAD || this->action_type == GLAT_GRF); - LoggedChange *lc = GamelogChange(GLCT_GRFCOMPAT); + LoggedChange *lc = this->Change(GLCT_GRFCOMPAT); if (lc == nullptr) return; lc->grfcompat = *newg; @@ -647,11 +617,11 @@ void GamelogGRFCompatible(const GRFIdentifier *newg) * @param grfid GRF that is moved * @param offset how far it is moved, positive = moved down */ -static void GamelogGRFMove(uint32 grfid, int32 offset) +void Gamelog::GRFMove(uint32 grfid, int32 offset) { - assert(_gamelog_action_type == GLAT_GRF); + assert(this->action_type == GLAT_GRF); - LoggedChange *lc = GamelogChange(GLCT_GRFMOVE); + LoggedChange *lc = this->Change(GLCT_GRFMOVE); if (lc == nullptr) return; lc->grfmove.grfid = grfid; @@ -663,11 +633,11 @@ static void GamelogGRFMove(uint32 grfid, int32 offset) * Details about parameters changed are not stored * @param grfid ID of GRF to store */ -static void GamelogGRFParameters(uint32 grfid) +void Gamelog::GRFParameters(uint32 grfid) { - assert(_gamelog_action_type == GLAT_GRF); + assert(this->action_type == GLAT_GRF); - LoggedChange *lc = GamelogChange(GLCT_GRFPARAM); + LoggedChange *lc = this->Change(GLCT_GRFPARAM); if (lc == nullptr) return; lc->grfparam.grfid = grfid; @@ -678,12 +648,12 @@ static void GamelogGRFParameters(uint32 grfid) * Useful when old savegame is loaded or when new game is started * @param newg head of GRF linked list */ -void GamelogGRFAddList(const GRFConfig *newg) +void Gamelog::GRFAddList(const GRFConfig *newg) { - assert(_gamelog_action_type == GLAT_START || _gamelog_action_type == GLAT_LOAD); + assert(this->action_type == GLAT_START || this->action_type == GLAT_LOAD); for (; newg != nullptr; newg = newg->next) { - GamelogGRFAdd(newg); + this->GRFAdd(newg); } } @@ -719,7 +689,7 @@ static GRFList *GenerateGRFList(const GRFConfig *grfc) * @param oldc original GRF list * @param newc new GRF list */ -void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) +void Gamelog::GRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) { GRFList *ol = GenerateGRFList(oldc); GRFList *nl = GenerateGRFList(newc); @@ -742,7 +712,7 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) } if (oi == ol->n) { /* GRF couldn't be found in the OLD list, GRF was ADDED */ - GamelogGRFAdd(nl->grf[n++]); + this->GRFAdd(nl->grf[n++]); continue; } for (ni = 0; ni < nl->n; ni++) { @@ -755,7 +725,7 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) } if (ni == nl->n) { /* GRF couldn't be found in the NEW list, GRF was REMOVED */ - GamelogGRFRemove(ol->grf[o++]->ident.grfid); + this->GRFRemove(ol->grf[o++]->ident.grfid); continue; } @@ -769,18 +739,18 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) if (ni >= oi) { // prefer the one that is moved further /* GRF was moved down */ - GamelogGRFMove(ol->grf[o++]->ident.grfid, ni); + this->GRFMove(ol->grf[o++]->ident.grfid, ni); } else { - GamelogGRFMove(nl->grf[n++]->ident.grfid, -(int)oi); + this->GRFMove(nl->grf[n++]->ident.grfid, -(int)oi); } } else { if (memcmp(og->ident.md5sum, ng->ident.md5sum, sizeof(og->ident.md5sum)) != 0) { /* md5sum changed, probably loading 'compatible' GRF */ - GamelogGRFCompatible(&nl->grf[n]->ident); + this->GRFCompatible(&nl->grf[n]->ident); } if (og->num_params != ng->num_params || memcmp(og->param, ng->param, og->num_params * sizeof(og->param[0])) != 0) { - GamelogGRFParameters(ol->grf[o]->ident.grfid); + this->GRFParameters(ol->grf[o]->ident.grfid); } o++; @@ -788,8 +758,8 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) } } - while (o < ol->n) GamelogGRFRemove(ol->grf[o++]->ident.grfid); // remaining GRFs were removed ... - while (n < nl->n) GamelogGRFAdd (nl->grf[n++]); // ... or added + while (o < ol->n) this->GRFRemove(ol->grf[o++]->ident.grfid); // remaining GRFs were removed ... + while (n < nl->n) this->GRFAdd (nl->grf[n++]); // ... or added free(ol); free(nl); @@ -797,24 +767,20 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) /** * Get some basic information from the given gamelog. - * @param gamelog_action Pointer to the gamelog to extract information from. - * @param gamelog_actions Number of actions in the given gamelog. * @param[out] last_ottd_rev OpenTTD NewGRF version from the binary that saved the savegame last. * @param[out] ever_modified Max value of 'modified' from all binaries that ever saved this savegame. * @param[out] removed_newgrfs Set to true if any NewGRFs have been removed. */ -void GamelogInfo(LoggedAction *gamelog_action, uint gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs) +void Gamelog::Info(uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs) { - const LoggedAction *laend = &gamelog_action[gamelog_actions]; - for (const LoggedAction *la = gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - switch (lc->ct) { + for (const LoggedAction &la : this->data->action) { + for (const LoggedChange &lc : la.change) { + switch (lc.ct) { default: break; case GLCT_REVISION: - *last_ottd_rev = lc->revision.newgrf; - *ever_modified = std::max(*ever_modified, lc->revision.modified); + *last_ottd_rev = lc.revision.newgrf; + *ever_modified = std::max(*ever_modified, lc.revision.modified); break; case GLCT_GRFREM: @@ -824,3 +790,21 @@ void GamelogInfo(LoggedAction *gamelog_action, uint gamelog_actions, uint32 *las } } } + +/** + * Try to find the overridden GRF identifier of the given GRF. + * @param c the GRF to get the 'previous' version of. + * @return the GRF identifier or \a c if none could be found. + */ +const GRFIdentifier *Gamelog::GetOverriddenIdentifier(const GRFConfig *c) +{ + assert(c != nullptr); + const LoggedAction &la = this->data->action.back(); + if (la.at != GLAT_LOAD) return &c->ident; + + for (const LoggedChange &lc : la.change) { + if (lc.ct == GLCT_GRFCOMPAT && lc.grfcompat.grfid == c->ident.grfid) return &lc.grfcompat; + } + + return &c->ident; +} diff --git a/src/gamelog.h b/src/gamelog.h index 0555ca5e77..aa47575972 100644 --- a/src/gamelog.h +++ b/src/gamelog.h @@ -26,36 +26,77 @@ enum GamelogActionType : uint8 { GLAT_NONE = 0xFF, ///< No logging active; in savegames, end of list }; -void GamelogStartAction(GamelogActionType at); -void GamelogStopAction(); -void GamelogStopAnyAction(); +/** Type of logged change */ +enum GamelogChangeType : uint8 { + GLCT_MODE, ///< Scenario editor x Game, different landscape + GLCT_REVISION, ///< Changed game revision string + GLCT_OLDVER, ///< Loaded from savegame without logged data + GLCT_SETTING, ///< Non-networksafe setting value changed + GLCT_GRFADD, ///< Removed GRF + GLCT_GRFREM, ///< Added GRF + GLCT_GRFCOMPAT, ///< Loading compatible GRF + GLCT_GRFPARAM, ///< GRF parameter changed + GLCT_GRFMOVE, ///< GRF order changed + GLCT_GRFBUG, ///< GRF bug triggered + GLCT_EMERGENCY, ///< Emergency savegame + GLCT_END, ///< So we know how many GLCTs are there + GLCT_NONE = 0xFF, ///< In savegames, end of list +}; + +struct LoggedChange; +struct LoggedAction; +struct GamelogInternalData; + +class Gamelog { +private: + std::unique_ptr data; + GamelogActionType action_type; + struct LoggedAction *current_action; + + LoggedChange *Change(GamelogChangeType ct); -void GamelogFree(struct LoggedAction *gamelog_action, uint gamelog_actions); -void GamelogReset(); +public: + Gamelog(); + ~Gamelog(); -void GamelogPrint(std::function proc); -void GamelogPrintDebug(int level); -void GamelogPrintConsole(); + void StartAction(GamelogActionType at); + void StopAction(); + void StopAnyAction(); -void GamelogEmergency(); -bool GamelogTestEmergency(); + void Reset(); -void GamelogRevision(); -void GamelogMode(); -void GamelogOldver(); -void GamelogSetting(const std::string &name, int32 oldval, int32 newval); + void Print(std::function proc); + void PrintDebug(int level); + void PrintConsole(); -void GamelogGRFUpdate(const GRFConfig *oldg, const GRFConfig *newg); -void GamelogGRFAddList(const GRFConfig *newg); -void GamelogGRFRemove(uint32 grfid); -void GamelogGRFAdd(const GRFConfig *newg); -void GamelogGRFCompatible(const GRFIdentifier *newg); + void Emergency(); + bool TestEmergency(); -void GamelogTestRevision(); -void GamelogTestMode(); + void Revision(); + void Mode(); + void Oldver(); + void Setting(const std::string &name, int32 oldval, int32 newval); -bool GamelogGRFBugReverse(uint32 grfid, uint16 internal_id); + void GRFUpdate(const GRFConfig *oldg, const GRFConfig *newg); + void GRFAddList(const GRFConfig *newg); + void GRFRemove(uint32 grfid); + void GRFAdd(const GRFConfig *newg); + void GRFBug(uint32 grfid, byte bug, uint64 data); + bool GRFBugReverse(uint32 grfid, uint16 internal_id); + void GRFCompatible(const GRFIdentifier *newg); + void GRFMove(uint32 grfid, int32 offset); + void GRFParameters(uint32 grfid); + + void TestRevision(); + void TestMode(); + + void Info(uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs); + const GRFIdentifier *GetOverriddenIdentifier(const GRFConfig *c); + + /* Saveload handler for gamelog needs access to internal data. */ + friend struct GLOGChunkHandler; +}; -void GamelogInfo(struct LoggedAction *gamelog_action, uint gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs); +extern Gamelog _gamelog; #endif /* GAMELOG_H */ diff --git a/src/gamelog_internal.h b/src/gamelog_internal.h index 95e4404b7b..7fc196093e 100644 --- a/src/gamelog_internal.h +++ b/src/gamelog_internal.h @@ -12,24 +12,6 @@ #include "gamelog.h" -/** Type of logged change */ -enum GamelogChangeType : uint8 { - GLCT_MODE, ///< Scenario editor x Game, different landscape - GLCT_REVISION, ///< Changed game revision string - GLCT_OLDVER, ///< Loaded from savegame without logged data - GLCT_SETTING, ///< Non-networksafe setting value changed - GLCT_GRFADD, ///< Removed GRF - GLCT_GRFREM, ///< Added GRF - GLCT_GRFCOMPAT, ///< Loading compatible GRF - GLCT_GRFPARAM, ///< GRF parameter changed - GLCT_GRFMOVE, ///< GRF order changed - GLCT_GRFBUG, ///< GRF bug triggered - GLCT_EMERGENCY, ///< Emergency savegame - GLCT_END, ///< So we know how many GLCTs are there - GLCT_NONE = 0xFF, ///< In savegames, end of list -}; - - static const uint GAMELOG_REVISION_LENGTH = 15; /** Contains information about one logged change */ @@ -73,18 +55,20 @@ struct LoggedChange { byte bug; ///< type of bug, @see enum GRFBugs } grfbug; }; + + ~LoggedChange(); }; /** Contains information about one logged action that caused at least one logged change */ struct LoggedAction { - LoggedChange *change; ///< First logged change in this action - uint32 changes; ///< Number of changes in this action + std::vector change; ///< First logged change in this action GamelogActionType at; ///< Type of action uint64 tick; ///< Tick when it happened }; -extern LoggedAction *_gamelog_action; -extern uint _gamelog_actions; +struct GamelogInternalData { + std::vector action; +}; #endif /* GAMELOG_INTERNAL_H */ diff --git a/src/misc.cpp b/src/misc.cpp index 408f294ee9..cb30e1c8f6 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -122,10 +122,10 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin ResetObjectToPlace(); - GamelogReset(); - GamelogStartAction(GLAT_START); - GamelogRevision(); - GamelogMode(); - GamelogGRFAddList(_grfconfig); - GamelogStopAction(); + _gamelog.Reset(); + _gamelog.StartAction(GLAT_START); + _gamelog.Revision(); + _gamelog.Mode(); + _gamelog.GRFAddList(_grfconfig); + _gamelog.StopAction(); } diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index e29092317b..0181556a86 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -1964,11 +1964,11 @@ static void NewGRFConfirmationCallback(Window *w, bool confirmed) CloseWindowByClass(WC_TEXTFILE); NewGRFWindow *nw = dynamic_cast(w); - GamelogStartAction(GLAT_GRF); - GamelogGRFUpdate(_grfconfig, nw->actives); // log GRF changes + _gamelog.StartAction(GLAT_GRF); + _gamelog.GRFUpdate(_grfconfig, nw->actives); // log GRF changes CopyGRFConfigList(nw->orig_list, nw->actives, false); ReloadNewGRFData(); - GamelogStopAction(); + _gamelog.StopAction(); /* Show new, updated list */ GRFConfig *c; diff --git a/src/openttd.cpp b/src/openttd.cpp index 380dcb3b4e..52a466f78d 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -241,7 +241,7 @@ static void WriteSavegameInfo(const char *name) byte ever_modified = 0; bool removed_newgrfs = false; - GamelogInfo(_load_check_data.gamelog_action, _load_check_data.gamelog_actions, &last_ottd_rev, &ever_modified, &removed_newgrfs); + _gamelog.Info(&last_ottd_rev, &ever_modified, &removed_newgrfs); std::string message; message.reserve(1024); @@ -311,7 +311,7 @@ static void ShutdownGame() Game::Uninitialize(false); /* Uninitialize variables that are allocated dynamically */ - GamelogReset(); + _gamelog.Reset(); LinkGraphSchedule::Clear(); PoolBase::Clean(PT_ALL); diff --git a/src/os/macosx/crashlog_osx.cpp b/src/os/macosx/crashlog_osx.cpp index 68e2e5633d..78c550aa9e 100644 --- a/src/os/macosx/crashlog_osx.cpp +++ b/src/os/macosx/crashlog_osx.cpp @@ -227,7 +227,7 @@ void CDECL HandleCrash(int signum) signal(*i, SIG_DFL); } - if (GamelogTestEmergency()) { + if (_gamelog.TestEmergency()) { ShowMacDialog("A serious fault condition occurred in the game. The game will shut down.", "As you loaded an emergency savegame no crash information will be generated.\n", "Quit"); diff --git a/src/os/unix/crashlog_unix.cpp b/src/os/unix/crashlog_unix.cpp index cb4103e693..a3fc1d5e97 100644 --- a/src/os/unix/crashlog_unix.cpp +++ b/src/os/unix/crashlog_unix.cpp @@ -155,7 +155,7 @@ static void CDECL HandleCrash(int signum) signal(*i, SIG_DFL); } - if (GamelogTestEmergency()) { + if (_gamelog.TestEmergency()) { printf("A serious fault condition occurred in the game. The game will shut down.\n"); printf("As you loaded an emergency savegame no crash information will be generated.\n"); abort(); diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index 6479f60a99..c4b5e9597e 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -540,7 +540,7 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep) ExitProcess(2); } - if (GamelogTestEmergency()) { + if (_gamelog.TestEmergency()) { static const wchar_t _emergency_crash[] = L"A serious fault condition occurred in the game. The game will shut down.\n" L"As you loaded an emergency savegame no crash information will be generated.\n"; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 5cd865030a..6e685164b9 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -340,24 +340,6 @@ static void ResetSignalHandlers() signal(SIGFPE, _prev_fpe); } -/** - * Try to find the overridden GRF identifier of the given GRF. - * @param c the GRF to get the 'previous' version of. - * @return the GRF identifier or \a c if none could be found. - */ -static const GRFIdentifier *GetOverriddenIdentifier(const GRFConfig *c) -{ - const LoggedAction *la = &_gamelog_action[_gamelog_actions - 1]; - if (la->at != GLAT_LOAD) return &c->ident; - - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_GRFCOMPAT && lc->grfcompat.grfid == c->ident.grfid) return &lc->grfcompat; - } - - return &c->ident; -} - /** Was the saveload crash because of missing NewGRFs? */ static bool _saveload_crash_with_missing_newgrfs = false; @@ -405,7 +387,7 @@ static void CDECL HandleSavegameLoadCrash(int signum) for (const GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (HasBit(c->flags, GCF_COMPATIBLE)) { - const GRFIdentifier *replaced = GetOverriddenIdentifier(c); + const GRFIdentifier *replaced = _gamelog.GetOverriddenIdentifier(c); char original_md5[40]; char replaced_md5[40]; md5sumToString(original_md5, lastof(original_md5), c->original_md5sum); @@ -591,10 +573,10 @@ bool AfterLoadGame() /* The LFSR used in RunTileLoop iteration cannot have a zeroed state, make it non-zeroed. */ if (_cur_tileloop_tile == 0) _cur_tileloop_tile = 1; - if (IsSavegameVersionBefore(SLV_98)) GamelogOldver(); + if (IsSavegameVersionBefore(SLV_98)) _gamelog.Oldver(); - GamelogTestRevision(); - GamelogTestMode(); + _gamelog.TestRevision(); + _gamelog.TestMode(); RebuildTownKdtree(); RebuildStationKdtree(); @@ -602,7 +584,7 @@ bool AfterLoadGame() * that otherwise won't exist in the tree. */ RebuildViewportKdtree(); - if (IsSavegameVersionBefore(SLV_98)) GamelogGRFAddList(_grfconfig); + if (IsSavegameVersionBefore(SLV_98)) _gamelog.GRFAddList(_grfconfig); if (IsSavegameVersionBefore(SLV_119)) { _pause_mode = (_pause_mode == 2) ? PM_PAUSED_NORMAL : PM_UNPAUSED; @@ -729,9 +711,9 @@ bool AfterLoadGame() GRFListCompatibility gcf_res = IsGoodGRFConfigList(_grfconfig); for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (c->status == GCS_NOT_FOUND) { - GamelogGRFRemove(c->ident.grfid); + _gamelog.GRFRemove(c->ident.grfid); } else if (HasBit(c->flags, GCF_COMPATIBLE)) { - GamelogGRFCompatible(&c->ident); + _gamelog.GRFCompatible(&c->ident); } } @@ -3260,7 +3242,7 @@ bool AfterLoadGame() AfterLoadCompanyStats(); AfterLoadStoryBook(); - GamelogPrintDebug(1); + _gamelog.PrintDebug(1); InitializeWindowsAndCaches(); /* Restore the signals */ diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index c1f627f10c..43f7d7b32d 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -298,12 +298,11 @@ public: void Save(LoggedAction *la) const override { - SlSetStructListLength(la->changes); + SlSetStructListLength(la->change.size()); - const LoggedChange *lcend = &la->change[la->changes]; - for (LoggedChange *lc = la->change; lc != lcend; lc++) { - assert((uint)lc->ct < GLCT_END); - SlObject(lc, this->GetDescription()); + for (auto &lc : la->change) { + assert((uint)lc.ct < GLCT_END); + SlObject(&lc, this->GetDescription()); } } @@ -315,27 +314,20 @@ public: if (type >= GLCT_END) SlErrorCorrupt("Invalid gamelog change type"); GamelogChangeType ct = (GamelogChangeType)type; - la->change = ReallocT(la->change, la->changes + 1); - - LoggedChange *lc = &la->change[la->changes++]; - memset(lc, 0, sizeof(*lc)); - lc->ct = ct; - - SlObject(lc, this->GetLoadDescription()); + LoggedChange &lc = la->change.emplace_back(); + lc.ct = ct; + SlObject(&lc, this->GetLoadDescription()); } return; } size_t length = SlGetStructListLength(UINT32_MAX); - la->change = ReallocT(la->change, length); - la->changes = (uint32)length; + la->change.reserve(length); for (size_t i = 0; i < length; i++) { - LoggedChange *lc = &la->change[i]; - memset(lc, 0, sizeof(*lc)); - - lc->ct = (GamelogChangeType)SlReadByte(); - SlObject(lc, this->GetLoadDescription()); + LoggedChange &lc = la->change.emplace_back(); + lc.ct = (GamelogChangeType)SlReadByte(); + SlObject(&lc, this->GetLoadDescription()); } } @@ -352,10 +344,9 @@ static const SaveLoad _gamelog_desc[] = { struct GLOGChunkHandler : ChunkHandler { GLOGChunkHandler() : ChunkHandler('GLOG', CH_TABLE) {} - void LoadCommon(LoggedAction *&gamelog_action, uint &gamelog_actions) const + void LoadCommon(Gamelog &gamelog) const { - assert(gamelog_action == nullptr); - assert(gamelog_actions == 0); + assert(gamelog.data->action.empty()); const std::vector slt = SlCompatTableHeader(_gamelog_desc, _gamelog_sl_compat); @@ -364,22 +355,16 @@ struct GLOGChunkHandler : ChunkHandler { while ((type = SlReadByte()) != GLAT_NONE) { if (type >= GLAT_END) SlErrorCorrupt("Invalid gamelog action type"); - gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1); - LoggedAction *la = &gamelog_action[gamelog_actions++]; - memset(la, 0, sizeof(*la)); - - la->at = (GamelogActionType)type; - SlObject(la, slt); + LoggedAction &la = gamelog.data->action.emplace_back(); + la.at = (GamelogActionType)type; + SlObject(&la, slt); } return; } while (SlIterateArray() != -1) { - gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1); - LoggedAction *la = &gamelog_action[gamelog_actions++]; - memset(la, 0, sizeof(*la)); - - SlObject(la, slt); + LoggedAction &la = gamelog.data->action.emplace_back(); + SlObject(&la, slt); } } @@ -387,23 +372,21 @@ struct GLOGChunkHandler : ChunkHandler { { SlTableHeader(_gamelog_desc); - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - uint i = 0; - for (LoggedAction *la = _gamelog_action; la != laend; la++, i++) { - SlSetArrayIndex(i); - SlObject(la, _gamelog_desc); + for (LoggedAction &la : _gamelog.data->action) { + SlSetArrayIndex(i++); + SlObject(&la, _gamelog_desc); } } void Load() const override { - this->LoadCommon(_gamelog_action, _gamelog_actions); + this->LoadCommon(_gamelog); } void LoadCheck(size_t) const override { - this->LoadCommon(_load_check_data.gamelog_action, _load_check_data.gamelog_actions); + this->LoadCommon(_load_check_data.gamelog); } }; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 0dc1baa10d..e756161550 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -348,7 +348,7 @@ void NORETURN SlError(StringID string, const std::string &extra_msg) if (_sl.action == SLA_LOAD || _sl.action == SLA_PTRS) SlNullPointers(); /* Logging could be active. */ - GamelogStopAnyAction(); + _gamelog.StopAnyAction(); throw std::exception(); } @@ -3129,7 +3129,7 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) * confuse old games */ InitializeGame(256, 256, true, true); - GamelogReset(); + _gamelog.Reset(); if (IsSavegameVersionBefore(SLV_4)) { /* @@ -3175,16 +3175,16 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) /* The only part from AfterLoadGame() we need */ _load_check_data.grf_compatibility = IsGoodGRFConfigList(_load_check_data.grfconfig); } else { - GamelogStartAction(GLAT_LOAD); + _gamelog.StartAction(GLAT_LOAD); /* After loading fix up savegame for any internal changes that * might have occurred since then. If it fails, load back the old game. */ if (!AfterLoadGame()) { - GamelogStopAction(); + _gamelog.StopAction(); return SL_REINIT; } - GamelogStopAction(); + _gamelog.StopAction(); } return SL_OK; @@ -3237,16 +3237,16 @@ SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, * Note: this is done here because AfterLoadGame is also called * for OTTD savegames which have their own NewGRF logic. */ ClearGRFConfigList(&_grfconfig); - GamelogReset(); + _gamelog.Reset(); if (!LoadOldSaveGame(filename)) return SL_REINIT; _sl_version = SL_MIN_VERSION; _sl_minor_version = 0; - GamelogStartAction(GLAT_LOAD); + _gamelog.StartAction(GLAT_LOAD); if (!AfterLoadGame()) { - GamelogStopAction(); + _gamelog.StopAction(); return SL_REINIT; } - GamelogStopAction(); + _gamelog.StopAction(); return SL_OK; } diff --git a/src/settings.cpp b/src/settings.cpp index 87e9c02208..6950485102 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1401,9 +1401,9 @@ void IntSettingDesc::ChangeValue(const void *object, int32 newval) const if (this->post_callback != nullptr) this->post_callback(newval); if (this->flags & SF_NO_NETWORK) { - GamelogStartAction(GLAT_SETTING); - GamelogSetting(this->GetName(), oldval, newval); - GamelogStopAction(); + _gamelog.StartAction(GLAT_SETTING); + _gamelog.Setting(this->GetName(), oldval, newval); + _gamelog.StopAction(); } SetWindowClassesDirty(WC_GAME_OPTIONS); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 20a401576b..d2f87e50e8 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -337,7 +337,7 @@ void VehicleLengthChanged(const Vehicle *u) const Engine *engine = u->GetEngine(); uint32 grfid = engine->grf_prop.grffile->grfid; GRFConfig *grfconfig = GetGRFConfig(grfid); - if (GamelogGRFBugReverse(grfid, engine->grf_prop.local_id) || !HasBit(grfconfig->grf_bugs, GBUG_VEH_LENGTH)) { + if (_gamelog.GRFBugReverse(grfid, engine->grf_prop.local_id) || !HasBit(grfconfig->grf_bugs, GBUG_VEH_LENGTH)) { ShowNewGrfVehicleError(u->engine_type, STR_NEWGRF_BROKEN, STR_NEWGRF_BROKEN_VEHICLE_LENGTH, GBUG_VEH_LENGTH, true); } } From 39eff18754638d7742aa24df946938e60051fe0a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 20 Jan 2023 16:00:18 +0000 Subject: [PATCH 07/34] Codechange: Use std::vector for gamelog GRFConfig comparisons. --- src/gamelog.cpp | 64 +++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/src/gamelog.cpp b/src/gamelog.cpp index e3b69f081f..7ec01a2e01 100644 --- a/src/gamelog.cpp +++ b/src/gamelog.cpp @@ -657,28 +657,15 @@ void Gamelog::GRFAddList(const GRFConfig *newg) } } -/** List of GRFs using array of pointers instead of linked list */ -struct GRFList { - uint n; - const GRFConfig *grf[]; -}; - /** * Generates GRFList * @param grfc head of GRF linked list */ -static GRFList *GenerateGRFList(const GRFConfig *grfc) +static std::vector GenerateGRFList(const GRFConfig *grfc) { - uint n = 0; + std::vector list; for (const GRFConfig *g = grfc; g != nullptr; g = g->next) { - if (IsLoggableGrfConfig(g)) n++; - } - - GRFList *list = (GRFList*)MallocT(sizeof(GRFList) + n * sizeof(GRFConfig*)); - - list->n = 0; - for (const GRFConfig *g = grfc; g != nullptr; g = g->next) { - if (IsLoggableGrfConfig(g)) list->grf[list->n++] = g; + if (IsLoggableGrfConfig(g)) list.push_back(g); } return list; @@ -691,66 +678,66 @@ static GRFList *GenerateGRFList(const GRFConfig *grfc) */ void Gamelog::GRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) { - GRFList *ol = GenerateGRFList(oldc); - GRFList *nl = GenerateGRFList(newc); + std::vector ol = GenerateGRFList(oldc); + std::vector nl = GenerateGRFList(newc); uint o = 0, n = 0; - while (o < ol->n && n < nl->n) { - const GRFConfig *og = ol->grf[o]; - const GRFConfig *ng = nl->grf[n]; + while (o < ol.size() && n < nl.size()) { + const GRFConfig *og = ol[o]; + const GRFConfig *ng = nl[n]; if (og->ident.grfid != ng->ident.grfid) { uint oi, ni; - for (oi = 0; oi < ol->n; oi++) { - if (ol->grf[oi]->ident.grfid == nl->grf[n]->ident.grfid) break; + for (oi = 0; oi < ol.size(); oi++) { + if (ol[oi]->ident.grfid == nl[n]->ident.grfid) break; } if (oi < o) { /* GRF was moved, this change has been logged already */ n++; continue; } - if (oi == ol->n) { + if (oi == ol.size()) { /* GRF couldn't be found in the OLD list, GRF was ADDED */ - this->GRFAdd(nl->grf[n++]); + this->GRFAdd(nl[n++]); continue; } - for (ni = 0; ni < nl->n; ni++) { - if (nl->grf[ni]->ident.grfid == ol->grf[o]->ident.grfid) break; + for (ni = 0; ni < nl.size(); ni++) { + if (nl[ni]->ident.grfid == ol[o]->ident.grfid) break; } if (ni < n) { /* GRF was moved, this change has been logged already */ o++; continue; } - if (ni == nl->n) { + if (ni == nl.size()) { /* GRF couldn't be found in the NEW list, GRF was REMOVED */ - this->GRFRemove(ol->grf[o++]->ident.grfid); + this->GRFRemove(ol[o++]->ident.grfid); continue; } /* o < oi < ol->n * n < ni < nl->n */ - assert(ni > n && ni < nl->n); - assert(oi > o && oi < ol->n); + assert(ni > n && ni < nl.size()); + assert(oi > o && oi < ol.size()); ni -= n; // number of GRFs it was moved downwards oi -= o; // number of GRFs it was moved upwards if (ni >= oi) { // prefer the one that is moved further /* GRF was moved down */ - this->GRFMove(ol->grf[o++]->ident.grfid, ni); + this->GRFMove(ol[o++]->ident.grfid, ni); } else { - this->GRFMove(nl->grf[n++]->ident.grfid, -(int)oi); + this->GRFMove(nl[n++]->ident.grfid, -(int)oi); } } else { if (memcmp(og->ident.md5sum, ng->ident.md5sum, sizeof(og->ident.md5sum)) != 0) { /* md5sum changed, probably loading 'compatible' GRF */ - this->GRFCompatible(&nl->grf[n]->ident); + this->GRFCompatible(&nl[n]->ident); } if (og->num_params != ng->num_params || memcmp(og->param, ng->param, og->num_params * sizeof(og->param[0])) != 0) { - this->GRFParameters(ol->grf[o]->ident.grfid); + this->GRFParameters(ol[o]->ident.grfid); } o++; @@ -758,11 +745,8 @@ void Gamelog::GRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) } } - while (o < ol->n) this->GRFRemove(ol->grf[o++]->ident.grfid); // remaining GRFs were removed ... - while (n < nl->n) this->GRFAdd (nl->grf[n++]); // ... or added - - free(ol); - free(nl); + while (o < ol.size()) this->GRFRemove(ol[o++]->ident.grfid); // remaining GRFs were removed ... + while (n < nl.size()) this->GRFAdd (nl[n++]); // ... or added } /** From fbad57ecf7d25e402c3531a701c5e0adc4c6d0df Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Tue, 2 May 2023 23:12:52 +0200 Subject: [PATCH 08/34] Change: [CI] update emscripten and liblzma to the latest version (#10757) --- .github/workflows/ci-build.yml | 6 ++-- .github/workflows/preview_build.yml | 6 ++-- os/emscripten/Dockerfile | 2 +- os/emscripten/emsdk-liblzma.patch | 46 ++++++++++++++++------------- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index c187e00e35..29fb6db54d 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-20.04 container: # If you change this version, change the number in the cache step too. - image: emscripten/emsdk:3.1.28 + image: emscripten/emsdk:3.1.37 steps: - name: Checkout @@ -30,7 +30,7 @@ jobs: uses: actions/cache@v3 with: path: /emsdk/upstream/emscripten/cache - key: 3.1.28-${{ runner.os }} + key: 3.1.37-${{ runner.os }} - name: Patch Emscripten to support LZMA run: | @@ -65,7 +65,7 @@ jobs: echo "::group::Build" echo "Running on $(nproc) cores" - cmake --build . -j $(nproc) -t openttd + cmake --build . -j $(nproc) --target openttd echo "::endgroup::" linux: diff --git a/.github/workflows/preview_build.yml b/.github/workflows/preview_build.yml index b1d7b917ef..b73d993665 100644 --- a/.github/workflows/preview_build.yml +++ b/.github/workflows/preview_build.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-20.04 container: # If you change this version, change the number in the cache step too. - image: emscripten/emsdk:3.1.28 + image: emscripten/emsdk:3.1.37 steps: - name: Update deployment status to in progress @@ -45,7 +45,7 @@ jobs: uses: actions/cache@v3 with: path: /emsdk/upstream/emscripten/cache - key: 3.1.28-${{ runner.os }} + key: 3.1.37-${{ runner.os }} - name: Patch Emscripten to support LZMA run: | @@ -83,7 +83,7 @@ jobs: echo "::group::Build" echo "Running on $(nproc) cores" - emmake make -j$(nproc) + cmake --build . -j $(nproc) --target openttd echo "::endgroup::" - name: Publish preview diff --git a/os/emscripten/Dockerfile b/os/emscripten/Dockerfile index ae3579ec0a..e92858df87 100644 --- a/os/emscripten/Dockerfile +++ b/os/emscripten/Dockerfile @@ -1,4 +1,4 @@ -FROM emscripten/emsdk:3.1.28 +FROM emscripten/emsdk:3.1.37 COPY emsdk-liblzma.patch / RUN cd /emsdk/upstream/emscripten && patch -p1 < /emsdk-liblzma.patch diff --git a/os/emscripten/emsdk-liblzma.patch b/os/emscripten/emsdk-liblzma.patch index fbb24e7ca9..7bfdd47de2 100644 --- a/os/emscripten/emsdk-liblzma.patch +++ b/os/emscripten/emsdk-liblzma.patch @@ -1,30 +1,20 @@ -From 90dd4d4c6b1cedec338ff5b375fffca93700f7bc Mon Sep 17 00:00:00 2001 +From 84d0e9112d5c87a714abd21ec8547921f46f37b5 Mon Sep 17 00:00:00 2001 From: milek7 Date: Tue, 8 Dec 2020 01:03:31 +0100 Subject: [PATCH] Add liblzma port --- -Source: https://github.com/emscripten-core/emscripten/pull/12990 + src/settings.js | 4 ++ + tools/ports/liblzma.py | 151 +++++++++++++++++++++++++++++++++++++++++ + tools/settings.py | 1 + + 3 files changed, 156 insertions(+) + create mode 100644 tools/ports/liblzma.py -Modifed by OpenTTD to have the bare minimum needed to work. Otherwise there -are constantly conflicts when trying to apply this patch to different versions -of emsdk. - -diff --git a/tools/settings.py b/tools/settings.py ---- a/tools/settings.py -+++ b/tools/settings.py -@@ -40,6 +40,7 @@ PORTS_SETTINGS = { - 'USE_SDL_NET', - 'USE_SDL_GFX', - 'USE_LIBJPEG', -+ 'USE_LIBLZMA', - 'USE_OGG', - 'USE_REGAL', - 'USE_BOOST_HEADERS', diff --git a/src/settings.js b/src/settings.js +index f93140d..7b6bec9 100644 --- a/src/settings.js +++ b/src/settings.js -@@ -1450,6 +1450,10 @@ var USE_GIFLIB = false; +@@ -1451,6 +1451,10 @@ var USE_GIFLIB = false; // [compile+link] var USE_LIBJPEG = false; @@ -35,9 +25,9 @@ diff --git a/src/settings.js b/src/settings.js // 1 = use libpng from emscripten-ports // [compile+link] var USE_LIBPNG = false; - diff --git a/tools/ports/liblzma.py b/tools/ports/liblzma.py new file mode 100644 +index 0000000..6872a8b --- /dev/null +++ b/tools/ports/liblzma.py @@ -0,0 +1,151 @@ @@ -51,8 +41,8 @@ new file mode 100644 +import logging +from pathlib import Path + -+VERSION = '5.4.0' -+HASH = '29b2cd25bb5b234b329ffe9547692d2c29be393db9d8d4ce70a66dfdaebd54433e79a89d80c57e58cd4559c3c68b9845507d5fedf3eec1c528a81e3d9ddbd811' ++VERSION = '5.4.2' ++HASH = '149f980338bea3d66de1ff5994b2b236ae1773135eda68b62b009df0c9dcdf5467f8cb2c06da95a71b6556d60bd3d21f475feced34d5dfdb80ee95416a2f9737' + + +def needed(settings): @@ -192,3 +182,17 @@ new file mode 100644 +#endif +#define VERSION "5.4.0" +''' +diff --git a/tools/settings.py b/tools/settings.py +index 10d6ca0..827e4a9 100644 +--- a/tools/settings.py ++++ b/tools/settings.py +@@ -40,6 +40,7 @@ PORTS_SETTINGS = { + 'USE_SDL_NET', + 'USE_SDL_GFX', + 'USE_LIBJPEG', ++ 'USE_LIBLZMA', + 'USE_OGG', + 'USE_REGAL', + 'USE_BOOST_HEADERS', +-- +2.34.1 From 018a26d9b6d443c78707896e0876adeb4da38ca7 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Tue, 2 May 2023 23:22:09 +0200 Subject: [PATCH 09/34] Fix: crash in emscripten when saving games (#10758) Don't allocate 128KB on stack, but rather on the heap. --- src/saveload/saveload.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index e756161550..d581e55e2e 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -2582,6 +2582,7 @@ struct ZlibLoadFilter : LoadFilter { /** Filter using Zlib compression. */ struct ZlibSaveFilter : SaveFilter { z_stream z; ///< Stream state we are writing to. + byte fwrite_buf[MEMORY_CHUNK_SIZE]; ///< Buffer for writing to the file. /** * Initialise this filter. @@ -2608,13 +2609,12 @@ struct ZlibSaveFilter : SaveFilter { */ void WriteLoop(byte *p, size_t len, int mode) { - byte buf[MEMORY_CHUNK_SIZE]; // output buffer uint n; this->z.next_in = p; this->z.avail_in = (uInt)len; do { - this->z.next_out = buf; - this->z.avail_out = sizeof(buf); + this->z.next_out = this->fwrite_buf; + this->z.avail_out = sizeof(this->fwrite_buf); /** * For the poor next soul who sees many valgrind warnings of the @@ -2626,8 +2626,8 @@ struct ZlibSaveFilter : SaveFilter { int r = deflate(&this->z, mode); /* bytes were emitted? */ - if ((n = sizeof(buf) - this->z.avail_out) != 0) { - this->chain->Write(buf, n); + if ((n = sizeof(this->fwrite_buf) - this->z.avail_out) != 0) { + this->chain->Write(this->fwrite_buf, n); } if (r == Z_STREAM_END) break; @@ -2710,6 +2710,7 @@ struct LZMALoadFilter : LoadFilter { /** Filter using LZMA compression. */ struct LZMASaveFilter : SaveFilter { lzma_stream lzma; ///< Stream state that we are writing to. + byte fwrite_buf[MEMORY_CHUNK_SIZE]; ///< Buffer for writing to the file. /** * Initialise this filter. @@ -2735,19 +2736,18 @@ struct LZMASaveFilter : SaveFilter { */ void WriteLoop(byte *p, size_t len, lzma_action action) { - byte buf[MEMORY_CHUNK_SIZE]; // output buffer size_t n; this->lzma.next_in = p; this->lzma.avail_in = len; do { - this->lzma.next_out = buf; - this->lzma.avail_out = sizeof(buf); + this->lzma.next_out = this->fwrite_buf; + this->lzma.avail_out = sizeof(this->fwrite_buf); lzma_ret r = lzma_code(&this->lzma, action); /* bytes were emitted? */ - if ((n = sizeof(buf) - this->lzma.avail_out) != 0) { - this->chain->Write(buf, n); + if ((n = sizeof(this->fwrite_buf) - this->lzma.avail_out) != 0) { + this->chain->Write(this->fwrite_buf, n); } if (r == LZMA_STREAM_END) break; if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code"); From 62f9bdb939cc8a03bab3b66e538598cce3f27f1f Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Tue, 2 May 2023 23:43:16 +0200 Subject: [PATCH 10/34] Fix: [CI] no need to build unit-tests for releases (#10759) We don't run them anyway. And LTO can be darn slow. --- .github/workflows/release-linux.yml | 2 +- .github/workflows/release-macos.yml | 4 ++-- .github/workflows/release-windows.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index 5ab2bcd9e6..0f8ba153c6 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -124,7 +124,7 @@ jobs: echo "::group::Build" echo "Running on $(nproc) cores" - cmake --build . -j $(nproc) + cmake --build . -j $(nproc) --target openttd echo "::endgroup::" - name: Create bundles diff --git a/.github/workflows/release-macos.yml b/.github/workflows/release-macos.yml index 2d93bb5023..1240fae0ab 100644 --- a/.github/workflows/release-macos.yml +++ b/.github/workflows/release-macos.yml @@ -107,7 +107,7 @@ jobs: echo "::group::Build" echo "Running on $(sysctl -n hw.logicalcpu) cores" - cmake --build . -j $(sysctl -n hw.logicalcpu) + cmake --build . -j $(sysctl -n hw.logicalcpu) --target openttd echo "::endgroup::" - name: Build x64 @@ -130,7 +130,7 @@ jobs: echo "::group::Build" echo "Running on $(sysctl -n hw.logicalcpu) cores" - cmake --build . -j $(sysctl -n hw.logicalcpu) + cmake --build . -j $(sysctl -n hw.logicalcpu) --target openttd echo "::endgroup::" - name: Create bundles diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index 391599ad7d..347cb03386 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -133,7 +133,7 @@ jobs: echo "::endgroup::" echo "::group::Build" - cmake --build . + cmake --build . --target openttd echo "::endgroup::" env: WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }} @@ -157,7 +157,7 @@ jobs: echo "::endgroup::" echo "::group::Build" - cmake --build . + cmake --build . --target openttd echo "::endgroup::" env: WINDOWS_CERTIFICATE_COMMON_NAME: ${{ secrets.WINDOWS_CERTIFICATE_COMMON_NAME }} From 7669aac86517a8dac55d889f089a3c79ba8d7f15 Mon Sep 17 00:00:00 2001 From: translators Date: Wed, 3 May 2023 18:40:51 +0000 Subject: [PATCH 11/34] Update: Translations from eints english (us): 14 changes by 2TallTyler --- src/lang/english_US.txt | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 9c6992417f..0c1c4e762e 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -931,8 +931,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copy the # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Game Options - - +STR_GAME_OPTIONS_TAB_GENERAL :General +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Choose general settings +STR_GAME_OPTIONS_TAB_GRAPHICS :Graphics +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Choose graphics settings +STR_GAME_OPTIONS_TAB_SOUND :Sound +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Choose sound and music settings + +STR_GAME_OPTIONS_VOLUME :Volume +STR_GAME_OPTIONS_SFX_VOLUME :Sound effects +STR_GAME_OPTIONS_MUSIC_VOLUME :Music + +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Currency units STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Currency units selection From 6501f84b4a60148d00b32c80581067948119d65e Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Thu, 4 May 2023 09:14:12 -0400 Subject: [PATCH 12/34] Codechange: Move calendar date functions inside TimerGameCalendar (#10753) --- src/CMakeLists.txt | 2 - src/build_vehicle_gui.cpp | 6 +- src/cheat_gui.cpp | 9 +- src/console_cmds.cpp | 5 +- src/crashlog.cpp | 9 +- src/date.cpp | 136 ------------------------- src/date_func.h | 28 ----- src/date_gui.cpp | 8 +- src/date_type.h | 12 +-- src/engine.cpp | 9 +- src/fios_gui.cpp | 4 +- src/gamelog.cpp | 2 +- src/genworld_gui.cpp | 10 +- src/graph_gui.cpp | 2 +- src/industry_cmd.cpp | 1 - src/landscape.cpp | 5 +- src/linkgraph/linkgraph_gui.cpp | 2 +- src/misc.cpp | 4 +- src/network/core/game_info.cpp | 5 +- src/network/core/tcp_coordinator.cpp | 2 +- src/network/core/tcp_turn.cpp | 2 +- src/network/core/udp.cpp | 2 +- src/network/network_admin.cpp | 4 +- src/network/network_gui.cpp | 12 +-- src/network/network_udp.cpp | 2 +- src/newgrf.cpp | 11 +- src/news_gui.cpp | 5 +- src/pathfinder/yapf/yapf_costcache.hpp | 2 +- src/saveload/afterload.cpp | 2 +- src/saveload/misc_sl.cpp | 2 +- src/saveload/oldloader_sl.cpp | 8 +- src/saveload/saveload.cpp | 2 +- src/script/api/script_date.cpp | 15 ++- src/settings.cpp | 1 + src/settings_type.h | 1 - src/station_cmd.cpp | 2 +- src/statusbar_gui.cpp | 1 + src/strings.cpp | 13 ++- src/subsidy_gui.cpp | 5 +- src/timer/timer_game_calendar.cpp | 129 ++++++++++++++++++++++- src/timer/timer_game_calendar.h | 13 +++ src/toolbar_gui.cpp | 9 +- src/vehicle.cpp | 1 - 43 files changed, 224 insertions(+), 281 deletions(-) delete mode 100644 src/date.cpp delete mode 100644 src/date_func.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 01fbf2f0cb..b5124200e3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -115,8 +115,6 @@ add_files( crashlog.h currency.cpp currency.h - date.cpp - date_func.h date_gui.cpp date_gui.h date_type.h diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index d7b4ea6930..8d632a66c6 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -23,7 +23,7 @@ #include "string_func.h" #include "strings_func.h" #include "window_func.h" -#include "date_func.h" +#include "timer/timer_game_calendar.h" #include "vehicle_func.h" #include "widgets/dropdown_func.h" #include "engine_gui.h" @@ -920,8 +920,8 @@ void TestedEngineDetails::FillDefaultCapacities(const Engine *e) int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, TestedEngineDetails &te) { const Engine *e = Engine::Get(engine_number); - YearMonthDay ymd; - ConvertDateToYMD(e->intro_date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(e->intro_date, &ymd); bool refittable = IsArticulatedVehicleRefittable(engine_number); bool articulated_cargo = false; diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 9a6ac26771..b2f4d74921 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -12,7 +12,6 @@ #include "cheat_type.h" #include "company_base.h" #include "company_func.h" -#include "date_func.h" #include "saveload/saveload.h" #include "vehicle_base.h" #include "textbuf_gui.h" @@ -108,9 +107,9 @@ static int32 ClickChangeDateCheat(int32 new_value, int32 change_direction) new_value = Clamp(new_value, MIN_YEAR, MAX_YEAR); if (new_value == TimerGameCalendar::year) return TimerGameCalendar::year; - YearMonthDay ymd; - ConvertDateToYMD(TimerGameCalendar::date, &ymd); - TimerGameCalendar::Date new_date = ConvertYMDToDate(new_value, ymd.month, ymd.day); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); + TimerGameCalendar::Date new_date = TimerGameCalendar::ConvertYMDToDate(new_value, ymd.month, ymd.day); /* Shift cached dates before we change the date. */ for (auto v : Vehicle::Iterate()) v->ShiftDates(new_date - TimerGameCalendar::date); @@ -323,7 +322,7 @@ struct CheatWindow : Window { switch (ce->str) { /* Display date for change date cheat */ case STR_CHEAT_CHANGE_DATE: - SetDParam(0, ConvertYMDToDate(MAX_YEAR, 11, 31)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 11, 31)); width = std::max(width, GetStringBoundingBox(ce->str).width); break; diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index eb6bb0cbd1..bc3a4434fa 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -29,7 +29,6 @@ #include "strings_func.h" #include "viewport_func.h" #include "window_func.h" -#include "date_func.h" #include "timer/timer_game_calendar.h" #include "company_func.h" #include "gamelog.h" @@ -1449,8 +1448,8 @@ DEF_CONSOLE_CMD(ConGetDate) return true; } - YearMonthDay ymd; - ConvertDateToYMD(TimerGameCalendar::date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); IConsolePrint(CC_DEFAULT, "Date: {:04d}-{:02d}-{:02d}", ymd.year, ymd.month + 1, ymd.day); return true; } diff --git a/src/crashlog.cpp b/src/crashlog.cpp index 9dda4d0b26..f6a34a6328 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -10,7 +10,6 @@ #include "stdafx.h" #include "crashlog.h" #include "gamelog.h" -#include "date_func.h" #include "timer/timer_game_calendar.h" #include "map_func.h" #include "rev.h" @@ -319,8 +318,8 @@ char *CrashLog::LogRecentNews(char *buffer, const char *last) const int i = 0; for (NewsItem *news = _latest_news; i < 32 && news != nullptr; news = news->prev, i++) { - YearMonthDay ymd; - ConvertDateToYMD(news->date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(news->date, &ymd); buffer += seprintf(buffer, last, "(%i-%02i-%02i) StringID: %u, Type: %u, Ref1: %u, %u, Ref2: %u, %u\n", ymd.year, ymd.month + 1, ymd.day, news->string_id, news->type, news->reftype1, news->ref1, news->reftype2, news->ref2); @@ -359,8 +358,8 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last) const buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n"); buffer += UTCTime::Format(buffer, last, "Crash at: %Y-%m-%d %H:%M:%S (UTC)\n"); - YearMonthDay ymd; - ConvertDateToYMD(TimerGameCalendar::date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i)\n\n", ymd.year, ymd.month + 1, ymd.day, TimerGameCalendar::date_fract); buffer = this->LogError(buffer, last, CrashLog::message.c_str()); diff --git a/src/date.cpp b/src/date.cpp deleted file mode 100644 index c1756a4498..0000000000 --- a/src/date.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file date.cpp Handling of dates in our native format and transforming them to something human readable. */ - -#include "stdafx.h" -#include "network/network.h" -#include "network/network_func.h" -#include "currency.h" -#include "window_func.h" -#include "settings_type.h" -#include "date_func.h" -#include "vehicle_base.h" -#include "rail_gui.h" -#include "linkgraph/linkgraph.h" -#include "saveload/saveload.h" -#include "newgrf_profiling.h" -#include "widgets/statusbar_widget.h" -#include "timer/timer.h" -#include "timer/timer_game_calendar.h" - -#include "safeguards.h" - -#define M(a, b) ((a << 5) | b) -static const uint16 _month_date_from_year_day[] = { - M( 0, 1), M( 0, 2), M( 0, 3), M( 0, 4), M( 0, 5), M( 0, 6), M( 0, 7), M( 0, 8), M( 0, 9), M( 0, 10), M( 0, 11), M( 0, 12), M( 0, 13), M( 0, 14), M( 0, 15), M( 0, 16), M( 0, 17), M( 0, 18), M( 0, 19), M( 0, 20), M( 0, 21), M( 0, 22), M( 0, 23), M( 0, 24), M( 0, 25), M( 0, 26), M( 0, 27), M( 0, 28), M( 0, 29), M( 0, 30), M( 0, 31), - M( 1, 1), M( 1, 2), M( 1, 3), M( 1, 4), M( 1, 5), M( 1, 6), M( 1, 7), M( 1, 8), M( 1, 9), M( 1, 10), M( 1, 11), M( 1, 12), M( 1, 13), M( 1, 14), M( 1, 15), M( 1, 16), M( 1, 17), M( 1, 18), M( 1, 19), M( 1, 20), M( 1, 21), M( 1, 22), M( 1, 23), M( 1, 24), M( 1, 25), M( 1, 26), M( 1, 27), M( 1, 28), M( 1, 29), - M( 2, 1), M( 2, 2), M( 2, 3), M( 2, 4), M( 2, 5), M( 2, 6), M( 2, 7), M( 2, 8), M( 2, 9), M( 2, 10), M( 2, 11), M( 2, 12), M( 2, 13), M( 2, 14), M( 2, 15), M( 2, 16), M( 2, 17), M( 2, 18), M( 2, 19), M( 2, 20), M( 2, 21), M( 2, 22), M( 2, 23), M( 2, 24), M( 2, 25), M( 2, 26), M( 2, 27), M( 2, 28), M( 2, 29), M( 2, 30), M( 2, 31), - M( 3, 1), M( 3, 2), M( 3, 3), M( 3, 4), M( 3, 5), M( 3, 6), M( 3, 7), M( 3, 8), M( 3, 9), M( 3, 10), M( 3, 11), M( 3, 12), M( 3, 13), M( 3, 14), M( 3, 15), M( 3, 16), M( 3, 17), M( 3, 18), M( 3, 19), M( 3, 20), M( 3, 21), M( 3, 22), M( 3, 23), M( 3, 24), M( 3, 25), M( 3, 26), M( 3, 27), M( 3, 28), M( 3, 29), M( 3, 30), - M( 4, 1), M( 4, 2), M( 4, 3), M( 4, 4), M( 4, 5), M( 4, 6), M( 4, 7), M( 4, 8), M( 4, 9), M( 4, 10), M( 4, 11), M( 4, 12), M( 4, 13), M( 4, 14), M( 4, 15), M( 4, 16), M( 4, 17), M( 4, 18), M( 4, 19), M( 4, 20), M( 4, 21), M( 4, 22), M( 4, 23), M( 4, 24), M( 4, 25), M( 4, 26), M( 4, 27), M( 4, 28), M( 4, 29), M( 4, 30), M( 4, 31), - M( 5, 1), M( 5, 2), M( 5, 3), M( 5, 4), M( 5, 5), M( 5, 6), M( 5, 7), M( 5, 8), M( 5, 9), M( 5, 10), M( 5, 11), M( 5, 12), M( 5, 13), M( 5, 14), M( 5, 15), M( 5, 16), M( 5, 17), M( 5, 18), M( 5, 19), M( 5, 20), M( 5, 21), M( 5, 22), M( 5, 23), M( 5, 24), M( 5, 25), M( 5, 26), M( 5, 27), M( 5, 28), M( 5, 29), M( 5, 30), - M( 6, 1), M( 6, 2), M( 6, 3), M( 6, 4), M( 6, 5), M( 6, 6), M( 6, 7), M( 6, 8), M( 6, 9), M( 6, 10), M( 6, 11), M( 6, 12), M( 6, 13), M( 6, 14), M( 6, 15), M( 6, 16), M( 6, 17), M( 6, 18), M( 6, 19), M( 6, 20), M( 6, 21), M( 6, 22), M( 6, 23), M( 6, 24), M( 6, 25), M( 6, 26), M( 6, 27), M( 6, 28), M( 6, 29), M( 6, 30), M( 6, 31), - M( 7, 1), M( 7, 2), M( 7, 3), M( 7, 4), M( 7, 5), M( 7, 6), M( 7, 7), M( 7, 8), M( 7, 9), M( 7, 10), M( 7, 11), M( 7, 12), M( 7, 13), M( 7, 14), M( 7, 15), M( 7, 16), M( 7, 17), M( 7, 18), M( 7, 19), M( 7, 20), M( 7, 21), M( 7, 22), M( 7, 23), M( 7, 24), M( 7, 25), M( 7, 26), M( 7, 27), M( 7, 28), M( 7, 29), M( 7, 30), M( 7, 31), - M( 8, 1), M( 8, 2), M( 8, 3), M( 8, 4), M( 8, 5), M( 8, 6), M( 8, 7), M( 8, 8), M( 8, 9), M( 8, 10), M( 8, 11), M( 8, 12), M( 8, 13), M( 8, 14), M( 8, 15), M( 8, 16), M( 8, 17), M( 8, 18), M( 8, 19), M( 8, 20), M( 8, 21), M( 8, 22), M( 8, 23), M( 8, 24), M( 8, 25), M( 8, 26), M( 8, 27), M( 8, 28), M( 8, 29), M( 8, 30), - M( 9, 1), M( 9, 2), M( 9, 3), M( 9, 4), M( 9, 5), M( 9, 6), M( 9, 7), M( 9, 8), M( 9, 9), M( 9, 10), M( 9, 11), M( 9, 12), M( 9, 13), M( 9, 14), M( 9, 15), M( 9, 16), M( 9, 17), M( 9, 18), M( 9, 19), M( 9, 20), M( 9, 21), M( 9, 22), M( 9, 23), M( 9, 24), M( 9, 25), M( 9, 26), M( 9, 27), M( 9, 28), M( 9, 29), M( 9, 30), M( 9, 31), - M(10, 1), M(10, 2), M(10, 3), M(10, 4), M(10, 5), M(10, 6), M(10, 7), M(10, 8), M(10, 9), M(10, 10), M(10, 11), M(10, 12), M(10, 13), M(10, 14), M(10, 15), M(10, 16), M(10, 17), M(10, 18), M(10, 19), M(10, 20), M(10, 21), M(10, 22), M(10, 23), M(10, 24), M(10, 25), M(10, 26), M(10, 27), M(10, 28), M(10, 29), M(10, 30), - M(11, 1), M(11, 2), M(11, 3), M(11, 4), M(11, 5), M(11, 6), M(11, 7), M(11, 8), M(11, 9), M(11, 10), M(11, 11), M(11, 12), M(11, 13), M(11, 14), M(11, 15), M(11, 16), M(11, 17), M(11, 18), M(11, 19), M(11, 20), M(11, 21), M(11, 22), M(11, 23), M(11, 24), M(11, 25), M(11, 26), M(11, 27), M(11, 28), M(11, 29), M(11, 30), M(11, 31), -}; -#undef M - -enum DaysTillMonth { - ACCUM_JAN = 0, - ACCUM_FEB = ACCUM_JAN + 31, - ACCUM_MAR = ACCUM_FEB + 29, - ACCUM_APR = ACCUM_MAR + 31, - ACCUM_MAY = ACCUM_APR + 30, - ACCUM_JUN = ACCUM_MAY + 31, - ACCUM_JUL = ACCUM_JUN + 30, - ACCUM_AUG = ACCUM_JUL + 31, - ACCUM_SEP = ACCUM_AUG + 31, - ACCUM_OCT = ACCUM_SEP + 30, - ACCUM_NOV = ACCUM_OCT + 31, - ACCUM_DEC = ACCUM_NOV + 30, -}; - -/** Number of days to pass from the first day in the year before reaching the first of a month. */ -static const uint16 _accum_days_for_month[] = { - ACCUM_JAN, ACCUM_FEB, ACCUM_MAR, ACCUM_APR, - ACCUM_MAY, ACCUM_JUN, ACCUM_JUL, ACCUM_AUG, - ACCUM_SEP, ACCUM_OCT, ACCUM_NOV, ACCUM_DEC, -}; - -/** - * Converts a Date to a Year, Month & Day. - * @param date the date to convert from - * @param ymd the year, month and day to write to - */ -void ConvertDateToYMD(TimerGameCalendar::Date date, YearMonthDay *ymd) -{ - /* Year determination in multiple steps to account for leap - * years. First do the large steps, then the smaller ones. - */ - - /* There are 97 leap years in 400 years */ - TimerGameCalendar::Year yr = 400 * (date / (DAYS_IN_YEAR * 400 + 97)); - int rem = date % (DAYS_IN_YEAR * 400 + 97); - uint16 x; - - if (rem >= DAYS_IN_YEAR * 100 + 25) { - /* There are 25 leap years in the first 100 years after - * every 400th year, as every 400th year is a leap year */ - yr += 100; - rem -= DAYS_IN_YEAR * 100 + 25; - - /* There are 24 leap years in the next couple of 100 years */ - yr += 100 * (rem / (DAYS_IN_YEAR * 100 + 24)); - rem = (rem % (DAYS_IN_YEAR * 100 + 24)); - } - - if (!IsLeapYear(yr) && rem >= DAYS_IN_YEAR * 4) { - /* The first 4 year of the century are not always a leap year */ - yr += 4; - rem -= DAYS_IN_YEAR * 4; - } - - /* There is 1 leap year every 4 years */ - yr += 4 * (rem / (DAYS_IN_YEAR * 4 + 1)); - rem = rem % (DAYS_IN_YEAR * 4 + 1); - - /* The last (max 3) years to account for; the first one - * can be, but is not necessarily a leap year */ - while (rem >= (IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR)) { - rem -= IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; - yr++; - } - - /* Skip the 29th of February in non-leap years */ - if (!IsLeapYear(yr) && rem >= ACCUM_MAR - 1) rem++; - - ymd->year = yr; - - x = _month_date_from_year_day[rem]; - ymd->month = x >> 5; - ymd->day = x & 0x1F; -} - -/** - * Converts a tuple of Year, Month and Day to a Date. - * @param year is a number between 0..MAX_YEAR - * @param month is a number between 0..11 - * @param day is a number between 1..31 - */ -TimerGameCalendar::Date ConvertYMDToDate(TimerGameCalendar::Year year, TimerGameCalendar::Month month, TimerGameCalendar::Day day) -{ - /* Day-offset in a leap year */ - int days = _accum_days_for_month[month] + day - 1; - - /* Account for the missing of the 29th of February in non-leap years */ - if (!IsLeapYear(year) && days >= ACCUM_MAR) days--; - - return DAYS_TILL(year) + days; -} diff --git a/src/date_func.h b/src/date_func.h deleted file mode 100644 index 829cba8538..0000000000 --- a/src/date_func.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file date_func.h Functions related to dates. */ - -#ifndef DATE_FUNC_H -#define DATE_FUNC_H - -#include "date_type.h" - -void ConvertDateToYMD(TimerGameCalendar::Date date, YearMonthDay *ymd); -TimerGameCalendar::Date ConvertYMDToDate(TimerGameCalendar::Year year, TimerGameCalendar::Month month, TimerGameCalendar::Day day); - -/** - * Checks whether the given year is a leap year or not. - * @param yr The year to check. - * @return True if \c yr is a leap year, otherwise false. - */ -static inline bool IsLeapYear(TimerGameCalendar::Year yr) -{ - return yr % 4 == 0 && (yr % 100 != 0 || yr % 400 == 0); -} - -#endif /* DATE_FUNC_H */ diff --git a/src/date_gui.cpp b/src/date_gui.cpp index ff8725d225..3667b2e932 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -9,11 +9,11 @@ #include "stdafx.h" #include "strings_func.h" -#include "date_func.h" #include "timer/timer_game_calendar.h" #include "window_func.h" #include "window_gui.h" #include "date_gui.h" +#include "date_type.h" #include "core/geometry_func.hpp" #include "widgets/dropdown_type.h" @@ -26,7 +26,7 @@ struct SetDateWindow : Window { SetDateCallback *callback; ///< Callback to call when a date has been selected void *callback_data; ///< Callback data pointer. - YearMonthDay date; ///< The currently selected date + TimerGameCalendar::YearMonthDay date; ///< The currently selected date TimerGameCalendar::Year min_year; ///< The minimum year in the year dropdown TimerGameCalendar::Year max_year; ///< The maximum year (inclusive) in the year dropdown @@ -52,7 +52,7 @@ struct SetDateWindow : Window { this->InitNested(window_number); if (initial_date == 0) initial_date = TimerGameCalendar::date; - ConvertDateToYMD(initial_date, &this->date); + TimerGameCalendar::ConvertDateToYMD(initial_date, &this->date); this->date.year = Clamp(this->date.year, min_year, max_year); } @@ -149,7 +149,7 @@ struct SetDateWindow : Window { break; case WID_SD_SET_DATE: - if (this->callback != nullptr) this->callback(this, ConvertYMDToDate(this->date.year, this->date.month, this->date.day), this->callback_data); + if (this->callback != nullptr) this->callback(this, TimerGameCalendar::ConvertYMDToDate(this->date.year, this->date.month, this->date.day), this->callback_data); this->Close(); break; } diff --git a/src/date_type.h b/src/date_type.h index 76bc256f89..ce77eddd8d 100644 --- a/src/date_type.h +++ b/src/date_type.h @@ -74,7 +74,7 @@ static const TimerGameCalendar::Year ORIGINAL_MAX_YEAR = 2090; /** * The offset in days from the 'TimerGameCalendar::date == 0' till - * 'ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)' + * 'TimerGameCalendar::ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)' */ #define DAYS_TILL_ORIGINAL_BASE_YEAR DAYS_TILL(ORIGINAL_BASE_YEAR) @@ -95,16 +95,6 @@ static const TimerGameCalendar::Year MAX_YEAR = 5000000; /** The number of days till the last day */ #define MAX_DAY (DAYS_TILL(MAX_YEAR + 1) - 1) -/** - * Data structure to convert between Date and triplet (year, month, and day). - * @see ConvertDateToYMD(), ConvertYMDToDate() - */ -struct YearMonthDay { - TimerGameCalendar::Year year; ///< Year (0...) - TimerGameCalendar::Month month; ///< Month (0..11) - TimerGameCalendar::Day day; ///< Day (1..31) -}; - static const TimerGameCalendar::Year INVALID_YEAR = -1; ///< Representation of an invalid year static const TimerGameCalendar::Date INVALID_DATE = -1; ///< Representation of an invalid date static const Ticks INVALID_TICKS = -1; ///< Representation of an invalid number of ticks diff --git a/src/engine.cpp b/src/engine.cpp index 12724d5155..65d9d77379 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -17,7 +17,6 @@ #include "strings_func.h" #include "core/random_func.hpp" #include "window_func.h" -#include "date_func.h" #include "autoreplace_gui.h" #include "string_func.h" #include "ai/ai.hpp" @@ -663,8 +662,8 @@ void SetYearEngineAgingStops() if (e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON) continue; /* Base year ending date on half the model life */ - YearMonthDay ymd; - ConvertDateToYMD(ei->base_intro + (ei->lifelength * DAYS_IN_LEAP_YEAR) / 2, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(ei->base_intro + (ei->lifelength * DAYS_IN_LEAP_YEAR) / 2, &ymd); _year_engine_aging_stops = std::max(_year_engine_aging_stops, ymd.year); } @@ -698,7 +697,7 @@ void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32 seed /* Don't randomise the start-date in the first two years after gamestart to ensure availability * of engines in early starting games. * Note: TTDP uses fixed 1922 */ - e->intro_date = ei->base_intro <= ConvertYMDToDate(_settings_game.game_creation.starting_year + 2, 0, 1) ? ei->base_intro : (TimerGameCalendar::Date)GB(r, 0, 9) + ei->base_intro; + e->intro_date = ei->base_intro <= TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year + 2, 0, 1) ? ei->base_intro : (TimerGameCalendar::Date)GB(r, 0, 9) + ei->base_intro; if (e->intro_date <= TimerGameCalendar::date) { e->age = (aging_date - e->intro_date) >> 5; e->company_avail = MAX_UVALUE(CompanyMask); @@ -745,7 +744,7 @@ void StartupOneEngine(Engine *e, TimerGameCalendar::Date aging_date, uint32 seed void StartupEngines() { /* Aging of vehicles stops, so account for that when starting late */ - const TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date, ConvertYMDToDate(_year_engine_aging_stops, 0, 1)); + const TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date, TimerGameCalendar::ConvertYMDToDate(_year_engine_aging_stops, 0, 1)); uint32 seed = Random(); for (Engine *e : Engine::Iterate()) { diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 1f2f8e5b8c..bfe14e486d 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -23,7 +23,7 @@ #include "querystring_gui.h" #include "engine_func.h" #include "landscape_type.h" -#include "date_func.h" +#include "timer/timer_game_calendar.h" #include "core/geometry_func.hpp" #include "gamelog.h" #include "stringfilter_type.h" @@ -520,7 +520,7 @@ public: /* Start date (if available) */ if (_load_check_data.settings.game_creation.starting_year != 0) { - SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1)); DrawString(tr, STR_NETWORK_SERVER_LIST_START_DATE); tr.top += FONT_HEIGHT_NORMAL; } diff --git a/src/gamelog.cpp b/src/gamelog.cpp index 7ec01a2e01..5ce866e32d 100644 --- a/src/gamelog.cpp +++ b/src/gamelog.cpp @@ -14,7 +14,7 @@ #include "gamelog_internal.h" #include "console_func.h" #include "debug.h" -#include "date_func.h" +#include "timer/timer_game_calendar.h" #include "timer/timer_game_tick.h" #include "rev.h" diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 306d073abd..b7fd49b48e 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -14,7 +14,7 @@ #include "network/network.h" #include "strings_func.h" #include "window_func.h" -#include "date_func.h" +#include "timer/timer_game_calendar.h" #include "sound_func.h" #include "fios.h" #include "string_func.h" @@ -437,7 +437,7 @@ struct GenerateLandscapeWindow : public Window { void SetStringParameters(int widget) const override { switch (widget) { - case WID_GL_START_DATE_TEXT: SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); break; + case WID_GL_START_DATE_TEXT: SetDParam(0, TimerGameCalendar::ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); break; case WID_GL_MAPSIZE_X_PULLDOWN: SetDParam(0, 1LL << _settings_newgame.game_creation.map_x); break; case WID_GL_MAPSIZE_Y_PULLDOWN: SetDParam(0, 1LL << _settings_newgame.game_creation.map_y); break; case WID_GL_HEIGHTMAP_HEIGHT_TEXT: SetDParam(0, _settings_newgame.game_creation.heightmap_height); break; @@ -600,7 +600,7 @@ struct GenerateLandscapeWindow : public Window { break; case WID_GL_START_DATE_TEXT: - SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 0, 1)); d = GetStringBoundingBox(STR_BLACK_DATE_LONG); break; @@ -1107,7 +1107,7 @@ struct CreateScenarioWindow : public Window { switch (widget) { case WID_CS_START_DATE_TEXT: - SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); break; case WID_CS_MAPSIZE_X_PULLDOWN: @@ -1144,7 +1144,7 @@ struct CreateScenarioWindow : public Window StringID str = STR_JUST_INT; switch (widget) { case WID_CS_START_DATE_TEXT: - SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 0, 1)); str = STR_BLACK_DATE_LONG; break; diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 95776837a9..5510aa7439 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -17,12 +17,12 @@ #include "strings_func.h" #include "window_func.h" #include "date_type.h" -#include "timer/timer_game_calendar.h" #include "gfx_func.h" #include "core/geometry_func.hpp" #include "currency.h" #include "timer/timer.h" #include "timer/timer_window.h" +#include "timer/timer_game_calendar.h" #include "zoom_func.h" #include "widgets/graph_widget.h" diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index ba9309e9ae..67860ebfd4 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -27,7 +27,6 @@ #include "water.h" #include "strings_func.h" #include "window_func.h" -#include "date_func.h" #include "vehicle_func.h" #include "sound_func.h" #include "animated_tile_func.h" diff --git a/src/landscape.cpp b/src/landscape.cpp index 65fc4f0640..297ec6bd77 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -21,7 +21,6 @@ #include "genworld.h" #include "fios.h" #include "error_func.h" -#include "date_func.h" #include "timer/timer_game_calendar.h" #include "timer/timer_game_tick.h" #include "water.h" @@ -613,8 +612,8 @@ byte GetSnowLine() { if (_snow_line == nullptr) return _settings_game.game_creation.snow_line_height; - YearMonthDay ymd; - ConvertDateToYMD(TimerGameCalendar::date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); return _snow_line->table[ymd.month][ymd.day]; } diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index bc8ca69175..3676a9cb0f 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -12,7 +12,7 @@ #include "../window_func.h" #include "../company_base.h" #include "../company_gui.h" -#include "../date_func.h" +#include "../timer/timer_game_calendar.h" #include "../viewport_func.h" #include "../zoom_func.h" #include "../smallmap_gui.h" diff --git a/src/misc.cpp b/src/misc.cpp index cb30e1c8f6..b8748d7b3b 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -15,7 +15,7 @@ #include "newgrf.h" #include "newgrf_house.h" #include "economy_func.h" -#include "date_func.h" +#include "timer/timer_game_calendar.h" #include "timer/timer_game_tick.h" #include "texteff.hpp" #include "gfx_func.h" @@ -74,7 +74,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin _newgrf_profilers.clear(); if (reset_date) { - TimerGameCalendar::SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0); + TimerGameCalendar::SetDate(TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0); InitializeOldNames(); } diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp index ab0564e548..0c4ce31672 100644 --- a/src/network/core/game_info.cpp +++ b/src/network/core/game_info.cpp @@ -13,7 +13,6 @@ #include "game_info.h" #include "../../core/bitmath_func.hpp" #include "../../company_base.h" -#include "../../date_func.h" #include "../../timer/timer_game_calendar.h" #include "../../debug.h" #include "../../map_func.h" @@ -124,7 +123,7 @@ void CheckGameCompatibility(NetworkGameInfo &ngi) void FillStaticNetworkServerGameInfo() { _network_game_info.use_password = !_settings_client.network.server_password.empty(); - _network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); + _network_game_info.start_date = TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); _network_game_info.clients_max = _settings_client.network.max_clients; _network_game_info.companies_max = _settings_client.network.max_companies; _network_game_info.map_width = Map::SizeX(); @@ -256,7 +255,7 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool */ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table) { - static const TimerGameCalendar::Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11 + static const TimerGameCalendar::Date MAX_DATE = TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11 byte game_info_version = p->Recv_uint8(); NewGRFSerializationType newgrf_serialisation = NST_GRFID_MD5; diff --git a/src/network/core/tcp_coordinator.cpp b/src/network/core/tcp_coordinator.cpp index 44395a905b..e10a3f9e01 100644 --- a/src/network/core/tcp_coordinator.cpp +++ b/src/network/core/tcp_coordinator.cpp @@ -10,7 +10,7 @@ */ #include "../../stdafx.h" -#include "../../date_func.h" +#include "../../timer/timer_game_calendar.h" #include "../../debug.h" #include "tcp_coordinator.h" diff --git a/src/network/core/tcp_turn.cpp b/src/network/core/tcp_turn.cpp index 026b641943..c3c3ff8d83 100644 --- a/src/network/core/tcp_turn.cpp +++ b/src/network/core/tcp_turn.cpp @@ -10,7 +10,7 @@ */ #include "../../stdafx.h" -#include "../../date_func.h" +#include "../../timer/timer_game_calendar.h" #include "../../debug.h" #include "tcp_turn.h" diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index b4fcec5b84..f1f74bcf34 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -10,7 +10,7 @@ */ #include "../../stdafx.h" -#include "../../date_func.h" +#include "../../timer/timer_game_calendar.h" #include "../../debug.h" #include "game_info.h" #include "udp.h" diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index efd1eecda1..7e9433efdf 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -9,7 +9,7 @@ #include "../stdafx.h" #include "../strings_func.h" -#include "../date_func.h" +#include "../timer/timer_game_calendar.h" #include "../timer/timer_game_calendar.h" #include "core/game_info.h" #include "network_admin.h" @@ -178,7 +178,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome() p->Send_string(""); // Used to be map-name. p->Send_uint32(_settings_game.game_creation.generation_seed); p->Send_uint8 (_settings_game.game_creation.landscape); - p->Send_uint32(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1)); + p->Send_uint32(TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1)); p->Send_uint16(Map::SizeX()); p->Send_uint16(Map::SizeY()); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 3e29c0dcd7..5c0e21936d 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -9,7 +9,6 @@ #include "../stdafx.h" #include "../strings_func.h" -#include "../date_func.h" #include "../fios.h" #include "network_client.h" #include "network_gui.h" @@ -38,6 +37,7 @@ #include "../company_cmd.h" #include "../timer/timer.h" #include "../timer/timer_window.h" +#include "../timer/timer_game_calendar.h" #include "../widgets/network_widget.h" @@ -432,8 +432,8 @@ protected: if (nwi_header->IsWidgetVisible(WID_NG_DATE)) { /* current date */ Rect date = this->GetWidget(WID_NG_DATE)->GetCurrentRect(); - YearMonthDay ymd; - ConvertDateToYMD(cur_item->info.game_date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(cur_item->info.game_date, &ymd); SetDParam(0, ymd.year); DrawString(date.left, date.right, y + text_y_offset, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER); } @@ -441,9 +441,9 @@ protected: if (nwi_header->IsWidgetVisible(WID_NG_YEARS)) { /* number of years the game is running */ Rect years = this->GetWidget(WID_NG_YEARS)->GetCurrentRect(); - YearMonthDay ymd_cur, ymd_start; - ConvertDateToYMD(cur_item->info.game_date, &ymd_cur); - ConvertDateToYMD(cur_item->info.start_date, &ymd_start); + TimerGameCalendar::YearMonthDay ymd_cur, ymd_start; + TimerGameCalendar::ConvertDateToYMD(cur_item->info.game_date, &ymd_cur); + TimerGameCalendar::ConvertDateToYMD(cur_item->info.start_date, &ymd_start); SetDParam(0, ymd_cur.year - ymd_start.year); DrawString(years.left, years.right, y + text_y_offset, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER); } diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 3deb7e3129..6aed7d0f10 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -13,7 +13,7 @@ */ #include "../stdafx.h" -#include "../date_func.h" +#include "../timer/timer_game_calendar.h" #include "../map_func.h" #include "../debug.h" #include "core/game_info.h" diff --git a/src/newgrf.cpp b/src/newgrf.cpp index abbba142c1..4336e7b76f 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -37,7 +37,6 @@ #include "rev.h" #include "fios.h" #include "strings_func.h" -#include "date_func.h" #include "timer/timer_game_tick.h" #include "timer/timer_game_calendar.h" #include "string_func.h" @@ -6513,10 +6512,10 @@ bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile) return true; case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24) - YearMonthDay ymd; - ConvertDateToYMD(TimerGameCalendar::date, &ymd); - TimerGameCalendar::Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1); - *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (TimerGameCalendar::date - start_of_year) << 16; + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); + TimerGameCalendar::Date start_of_year = TimerGameCalendar::ConvertYMDToDate(ymd.year, 0, 1); + *value = ymd.month | (ymd.day - 1) << 8 | (TimerGameCalendar::IsLeapYear(ymd.year) ? 1 << 15 : 0) | (TimerGameCalendar::date - start_of_year) << 16; return true; } @@ -9947,7 +9946,7 @@ void LoadNewGRF(uint load_index, uint num_baseset) if (_networking) { TimerGameCalendar::year = _settings_game.game_creation.starting_year; - TimerGameCalendar::date = ConvertYMDToDate(TimerGameCalendar::year, 0, 1); + TimerGameCalendar::date = TimerGameCalendar::ConvertYMDToDate(TimerGameCalendar::year, 0, 1); TimerGameCalendar::date_fract = 0; TimerGameTick::counter = 0; _display_opt = 0; diff --git a/src/news_gui.cpp b/src/news_gui.cpp index a82d5a0a22..c48f6794bd 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -12,8 +12,6 @@ #include "viewport_func.h" #include "strings_func.h" #include "window_func.h" -#include "date_func.h" -#include "timer/timer_game_calendar.h" #include "vehicle_base.h" #include "vehicle_func.h" #include "vehicle_gui.h" @@ -38,6 +36,7 @@ #include "news_cmd.h" #include "timer/timer.h" #include "timer/timer_window.h" +#include "timer/timer_game_calendar.h" #include "widgets/news_widget.h" @@ -1155,7 +1154,7 @@ struct MessageHistoryWindow : Window { /* Months are off-by-one, so it's actually 8. Not using * month 12 because the 1 is usually less wide. */ - SetDParam(0, ConvertYMDToDate(ORIGINAL_MAX_YEAR, 7, 30)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(ORIGINAL_MAX_YEAR, 7, 30)); this->date_width = GetStringBoundingBox(STR_SHORT_DATE).width + WidgetDimensions::scaled.hsep_wide; size->height = 4 * resize->height + WidgetDimensions::scaled.framerect.Vertical(); // At least 4 lines are visible. diff --git a/src/pathfinder/yapf/yapf_costcache.hpp b/src/pathfinder/yapf/yapf_costcache.hpp index 1b4d52cff2..a1cd0625a9 100644 --- a/src/pathfinder/yapf/yapf_costcache.hpp +++ b/src/pathfinder/yapf/yapf_costcache.hpp @@ -10,7 +10,7 @@ #ifndef YAPF_COSTCACHE_HPP #define YAPF_COSTCACHE_HPP -#include "../../date_func.h" +#include "../../timer/timer_game_calendar.h" /** * CYapfSegmentCostCacheNoneT - the formal only yapf cost cache provider that implements diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 6e685164b9..0b8ae1cff7 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -22,7 +22,6 @@ #include "../clear_map.h" #include "../vehicle_func.h" #include "../string_func.h" -#include "../date_func.h" #include "../roadveh.h" #include "../roadveh_cmd.h" #include "../train.h" @@ -59,6 +58,7 @@ #include "../ship.h" #include "../water.h" #include "../timer/timer.h" +#include "../timer/timer_game_calendar.h" #include "../timer/timer_game_tick.h" #include "saveload_internal.h" diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index 3caa0fbab1..5ac6e93b02 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -12,7 +12,6 @@ #include "saveload.h" #include "compat/misc_sl_compat.h" -#include "../date_func.h" #include "../timer/timer_game_calendar.h" #include "../zoom_func.h" #include "../window_gui.h" @@ -21,6 +20,7 @@ #include "../gfx_func.h" #include "../core/random_func.hpp" #include "../fios.h" +#include "../date_type.h" #include "../timer/timer.h" #include "../timer/timer_game_tick.h" diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 4e312db541..723d142a6c 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -20,7 +20,7 @@ #include "../subsidy_base.h" #include "../debug.h" #include "../depot_base.h" -#include "../date_func.h" +#include "../timer/timer_game_calendar.h" #include "../timer/timer_game_calendar.h" #include "../vehicle_func.h" #include "../effectvehicle_base.h" @@ -400,7 +400,7 @@ static bool FixTTOEngines() for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i); } - TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + DAYS_TILL_ORIGINAL_BASE_YEAR, ConvertYMDToDate(2050, 0, 1)); + TimerGameCalendar::Date aging_date = std::min(TimerGameCalendar::date + DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::ConvertYMDToDate(2050, 0, 1)); for (EngineID i = 0; i < 256; i++) { int oi = ttd_to_tto[i]; @@ -847,8 +847,8 @@ static bool LoadOldIndustry(LoadgameState *ls, int num) if (i->type > 0x06) i->type++; // Printing Works were added if (i->type == 0x0A) i->type = 0x12; // Iron Ore Mine has different ID - YearMonthDay ymd; - ConvertDateToYMD(TimerGameCalendar::date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); i->last_prod_year = ymd.year; i->random_colour = RemapTTOColour(i->random_colour); diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index d581e55e2e..2db6efa1ae 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -31,7 +31,7 @@ #include "../core/endian_func.hpp" #include "../vehicle_base.h" #include "../company_func.h" -#include "../date_func.h" +#include "../timer/timer_game_calendar.h" #include "../autoreplace_base.h" #include "../roadstop_base.h" #include "../linkgraph/linkgraph.h" diff --git a/src/script/api/script_date.cpp b/src/script/api/script_date.cpp index c6a3438300..56ad8b8827 100644 --- a/src/script/api/script_date.cpp +++ b/src/script/api/script_date.cpp @@ -9,7 +9,6 @@ #include "../../stdafx.h" #include "script_date.hpp" -#include "../../date_func.h" #include "../../timer/timer_game_calendar.h" #include @@ -30,8 +29,8 @@ { if (date < 0) return DATE_INVALID; - ::YearMonthDay ymd; - ::ConvertDateToYMD(date, &ymd); + ::TimerGameCalendar::YearMonthDay ymd; + ::TimerGameCalendar::ConvertDateToYMD(date, &ymd); return ymd.year; } @@ -39,8 +38,8 @@ { if (date < 0) return DATE_INVALID; - ::YearMonthDay ymd; - ::ConvertDateToYMD(date, &ymd); + ::TimerGameCalendar::YearMonthDay ymd; + ::TimerGameCalendar::ConvertDateToYMD(date, &ymd); return ymd.month + 1; } @@ -48,8 +47,8 @@ { if (date < 0) return DATE_INVALID; - ::YearMonthDay ymd; - ::ConvertDateToYMD(date, &ymd); + ::TimerGameCalendar::YearMonthDay ymd; + ::TimerGameCalendar::ConvertDateToYMD(date, &ymd); return ymd.day; } @@ -59,7 +58,7 @@ if (day_of_month < 1 || day_of_month > 31) return DATE_INVALID; if (year < 0 || year > MAX_YEAR) return DATE_INVALID; - return (ScriptDate::Date)::ConvertYMDToDate(year, month - 1, day_of_month); + return (ScriptDate::Date)::TimerGameCalendar::ConvertYMDToDate(year, month - 1, day_of_month); } /* static */ SQInteger ScriptDate::GetSystemTime() diff --git a/src/settings.cpp b/src/settings.cpp index 6950485102..a71846e58a 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -45,6 +45,7 @@ #include "fios.h" #include "fileio_func.h" #include "settings_cmd.h" +#include "date_type.h" #include "table/strings.h" diff --git a/src/settings_type.h b/src/settings_type.h index 0804739f52..34284bc6a8 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -10,7 +10,6 @@ #ifndef SETTINGS_TYPE_H #define SETTINGS_TYPE_H -#include "date_type.h" #include "timer/timer_game_calendar.h" #include "economy_type.h" #include "town_type.h" diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 2e9ad663d4..e3b2e632f4 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -29,7 +29,7 @@ #include "water.h" #include "strings_func.h" #include "clear_func.h" -#include "date_func.h" +#include "timer/timer_game_calendar.h" #include "vehicle_func.h" #include "string_func.h" #include "animated_tile_func.h" diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index ad9710c66a..ffd788065a 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -25,6 +25,7 @@ #include "toolbar_gui.h" #include "core/geometry_func.hpp" #include "zoom_func.h" +#include "date_type.h" #include "timer/timer.h" #include "timer/timer_game_calendar.h" #include "timer/timer_window.h" diff --git a/src/strings.cpp b/src/strings.cpp index 5b88f3444d..840b064e5a 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -23,7 +23,6 @@ #include "strings_func.h" #include "rev.h" #include "core/endian_func.hpp" -#include "date_func.h" #include "timer/timer_game_calendar.h" #include "vehicle_base.h" #include "engine_base.h" @@ -428,8 +427,8 @@ static char *FormatBytes(char *buff, int64 number, const char *last) static char *FormatYmdString(char *buff, TimerGameCalendar::Date date, const char *last, uint case_index) { - YearMonthDay ymd; - ConvertDateToYMD(date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(date, &ymd); int64 args[] = {ymd.day + STR_DAY_NUMBER_1ST - 1, STR_MONTH_ABBREV_JAN + ymd.month, ymd.year}; StringParameters tmp_params(args); @@ -438,8 +437,8 @@ static char *FormatYmdString(char *buff, TimerGameCalendar::Date date, const cha static char *FormatMonthAndYear(char *buff, TimerGameCalendar::Date date, const char *last, uint case_index) { - YearMonthDay ymd; - ConvertDateToYMD(date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(date, &ymd); int64 args[] = {STR_MONTH_JAN + ymd.month, ymd.year}; StringParameters tmp_params(args); @@ -448,8 +447,8 @@ static char *FormatMonthAndYear(char *buff, TimerGameCalendar::Date date, const static char *FormatTinyOrISODate(char *buff, TimerGameCalendar::Date date, StringID str, const char *last) { - YearMonthDay ymd; - ConvertDateToYMD(date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(date, &ymd); /* Day and month are zero-padded with ZEROFILL_NUM, hence the two 2s. */ int64 args[] = {ymd.day, 2, ymd.month + 1, 2, ymd.year}; diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp index a5a2125880..d19c6e750d 100644 --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.cpp @@ -12,7 +12,6 @@ #include "town.h" #include "window_gui.h" #include "strings_func.h" -#include "date_func.h" #include "timer/timer_game_calendar.h" #include "viewport_func.h" #include "gui.h" @@ -143,8 +142,8 @@ struct SubsidyListWindow : Window { { if (widget != WID_SUL_PANEL) return; - YearMonthDay ymd; - ConvertDateToYMD(TimerGameCalendar::date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); diff --git a/src/timer/timer_game_calendar.cpp b/src/timer/timer_game_calendar.cpp index 50e3b65893..7ca331bab4 100644 --- a/src/timer/timer_game_calendar.cpp +++ b/src/timer/timer_game_calendar.cpp @@ -11,7 +11,6 @@ */ #include "stdafx.h" -#include "date_func.h" #include "openttd.h" #include "timer.h" #include "timer_game_calendar.h" @@ -25,6 +24,126 @@ TimerGameCalendar::Month TimerGameCalendar::month = {}; TimerGameCalendar::Date TimerGameCalendar::date = {}; TimerGameCalendar::DateFract TimerGameCalendar::date_fract = {}; +#define M(a, b) ((a << 5) | b) +static const uint16 _month_date_from_year_day[] = { + M(0, 1), M(0, 2), M(0, 3), M(0, 4), M(0, 5), M(0, 6), M(0, 7), M(0, 8), M(0, 9), M(0, 10), M(0, 11), M(0, 12), M(0, 13), M(0, 14), M(0, 15), M(0, 16), M(0, 17), M(0, 18), M(0, 19), M(0, 20), M(0, 21), M(0, 22), M(0, 23), M(0, 24), M(0, 25), M(0, 26), M(0, 27), M(0, 28), M(0, 29), M(0, 30), M(0, 31), + M(1, 1), M(1, 2), M(1, 3), M(1, 4), M(1, 5), M(1, 6), M(1, 7), M(1, 8), M(1, 9), M(1, 10), M(1, 11), M(1, 12), M(1, 13), M(1, 14), M(1, 15), M(1, 16), M(1, 17), M(1, 18), M(1, 19), M(1, 20), M(1, 21), M(1, 22), M(1, 23), M(1, 24), M(1, 25), M(1, 26), M(1, 27), M(1, 28), M(1, 29), + M(2, 1), M(2, 2), M(2, 3), M(2, 4), M(2, 5), M(2, 6), M(2, 7), M(2, 8), M(2, 9), M(2, 10), M(2, 11), M(2, 12), M(2, 13), M(2, 14), M(2, 15), M(2, 16), M(2, 17), M(2, 18), M(2, 19), M(2, 20), M(2, 21), M(2, 22), M(2, 23), M(2, 24), M(2, 25), M(2, 26), M(2, 27), M(2, 28), M(2, 29), M(2, 30), M(2, 31), + M(3, 1), M(3, 2), M(3, 3), M(3, 4), M(3, 5), M(3, 6), M(3, 7), M(3, 8), M(3, 9), M(3, 10), M(3, 11), M(3, 12), M(3, 13), M(3, 14), M(3, 15), M(3, 16), M(3, 17), M(3, 18), M(3, 19), M(3, 20), M(3, 21), M(3, 22), M(3, 23), M(3, 24), M(3, 25), M(3, 26), M(3, 27), M(3, 28), M(3, 29), M(3, 30), + M(4, 1), M(4, 2), M(4, 3), M(4, 4), M(4, 5), M(4, 6), M(4, 7), M(4, 8), M(4, 9), M(4, 10), M(4, 11), M(4, 12), M(4, 13), M(4, 14), M(4, 15), M(4, 16), M(4, 17), M(4, 18), M(4, 19), M(4, 20), M(4, 21), M(4, 22), M(4, 23), M(4, 24), M(4, 25), M(4, 26), M(4, 27), M(4, 28), M(4, 29), M(4, 30), M(4, 31), + M(5, 1), M(5, 2), M(5, 3), M(5, 4), M(5, 5), M(5, 6), M(5, 7), M(5, 8), M(5, 9), M(5, 10), M(5, 11), M(5, 12), M(5, 13), M(5, 14), M(5, 15), M(5, 16), M(5, 17), M(5, 18), M(5, 19), M(5, 20), M(5, 21), M(5, 22), M(5, 23), M(5, 24), M(5, 25), M(5, 26), M(5, 27), M(5, 28), M(5, 29), M(5, 30), + M(6, 1), M(6, 2), M(6, 3), M(6, 4), M(6, 5), M(6, 6), M(6, 7), M(6, 8), M(6, 9), M(6, 10), M(6, 11), M(6, 12), M(6, 13), M(6, 14), M(6, 15), M(6, 16), M(6, 17), M(6, 18), M(6, 19), M(6, 20), M(6, 21), M(6, 22), M(6, 23), M(6, 24), M(6, 25), M(6, 26), M(6, 27), M(6, 28), M(6, 29), M(6, 30), M(6, 31), + M(7, 1), M(7, 2), M(7, 3), M(7, 4), M(7, 5), M(7, 6), M(7, 7), M(7, 8), M(7, 9), M(7, 10), M(7, 11), M(7, 12), M(7, 13), M(7, 14), M(7, 15), M(7, 16), M(7, 17), M(7, 18), M(7, 19), M(7, 20), M(7, 21), M(7, 22), M(7, 23), M(7, 24), M(7, 25), M(7, 26), M(7, 27), M(7, 28), M(7, 29), M(7, 30), M(7, 31), + M(8, 1), M(8, 2), M(8, 3), M(8, 4), M(8, 5), M(8, 6), M(8, 7), M(8, 8), M(8, 9), M(8, 10), M(8, 11), M(8, 12), M(8, 13), M(8, 14), M(8, 15), M(8, 16), M(8, 17), M(8, 18), M(8, 19), M(8, 20), M(8, 21), M(8, 22), M(8, 23), M(8, 24), M(8, 25), M(8, 26), M(8, 27), M(8, 28), M(8, 29), M(8, 30), + M(9, 1), M(9, 2), M(9, 3), M(9, 4), M(9, 5), M(9, 6), M(9, 7), M(9, 8), M(9, 9), M(9, 10), M(9, 11), M(9, 12), M(9, 13), M(9, 14), M(9, 15), M(9, 16), M(9, 17), M(9, 18), M(9, 19), M(9, 20), M(9, 21), M(9, 22), M(9, 23), M(9, 24), M(9, 25), M(9, 26), M(9, 27), M(9, 28), M(9, 29), M(9, 30), M(9, 31), + M(10, 1), M(10, 2), M(10, 3), M(10, 4), M(10, 5), M(10, 6), M(10, 7), M(10, 8), M(10, 9), M(10, 10), M(10, 11), M(10, 12), M(10, 13), M(10, 14), M(10, 15), M(10, 16), M(10, 17), M(10, 18), M(10, 19), M(10, 20), M(10, 21), M(10, 22), M(10, 23), M(10, 24), M(10, 25), M(10, 26), M(10, 27), M(10, 28), M(10, 29), M(10, 30), + M(11, 1), M(11, 2), M(11, 3), M(11, 4), M(11, 5), M(11, 6), M(11, 7), M(11, 8), M(11, 9), M(11, 10), M(11, 11), M(11, 12), M(11, 13), M(11, 14), M(11, 15), M(11, 16), M(11, 17), M(11, 18), M(11, 19), M(11, 20), M(11, 21), M(11, 22), M(11, 23), M(11, 24), M(11, 25), M(11, 26), M(11, 27), M(11, 28), M(11, 29), M(11, 30), M(11, 31), +}; +#undef M + +enum DaysTillMonth { + ACCUM_JAN = 0, + ACCUM_FEB = ACCUM_JAN + 31, + ACCUM_MAR = ACCUM_FEB + 29, + ACCUM_APR = ACCUM_MAR + 31, + ACCUM_MAY = ACCUM_APR + 30, + ACCUM_JUN = ACCUM_MAY + 31, + ACCUM_JUL = ACCUM_JUN + 30, + ACCUM_AUG = ACCUM_JUL + 31, + ACCUM_SEP = ACCUM_AUG + 31, + ACCUM_OCT = ACCUM_SEP + 30, + ACCUM_NOV = ACCUM_OCT + 31, + ACCUM_DEC = ACCUM_NOV + 30, +}; + +/** Number of days to pass from the first day in the year before reaching the first of a month. */ +static const uint16 _accum_days_for_month[] = { + ACCUM_JAN, ACCUM_FEB, ACCUM_MAR, ACCUM_APR, + ACCUM_MAY, ACCUM_JUN, ACCUM_JUL, ACCUM_AUG, + ACCUM_SEP, ACCUM_OCT, ACCUM_NOV, ACCUM_DEC, +}; + +/** + * Converts a Date to a Year, Month & Day. + * @param date the date to convert from + * @param ymd the year, month and day to write to + */ +/* static */ void TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::Date date, YearMonthDay *ymd) +{ + /* Year determination in multiple steps to account for leap + * years. First do the large steps, then the smaller ones. + */ + + /* There are 97 leap years in 400 years */ + TimerGameCalendar::Year yr = 400 * (date / (DAYS_IN_YEAR * 400 + 97)); + int rem = date % (DAYS_IN_YEAR * 400 + 97); + uint16 x; + + if (rem >= DAYS_IN_YEAR * 100 + 25) { + /* There are 25 leap years in the first 100 years after + * every 400th year, as every 400th year is a leap year */ + yr += 100; + rem -= DAYS_IN_YEAR * 100 + 25; + + /* There are 24 leap years in the next couple of 100 years */ + yr += 100 * (rem / (DAYS_IN_YEAR * 100 + 24)); + rem = (rem % (DAYS_IN_YEAR * 100 + 24)); + } + + if (!TimerGameCalendar::IsLeapYear(yr) && rem >= DAYS_IN_YEAR * 4) { + /* The first 4 year of the century are not always a leap year */ + yr += 4; + rem -= DAYS_IN_YEAR * 4; + } + + /* There is 1 leap year every 4 years */ + yr += 4 * (rem / (DAYS_IN_YEAR * 4 + 1)); + rem = rem % (DAYS_IN_YEAR * 4 + 1); + + /* The last (max 3) years to account for; the first one + * can be, but is not necessarily a leap year */ + while (rem >= (TimerGameCalendar::IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR)) { + rem -= TimerGameCalendar::IsLeapYear(yr) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; + yr++; + } + + /* Skip the 29th of February in non-leap years */ + if (!TimerGameCalendar::IsLeapYear(yr) && rem >= ACCUM_MAR - 1) rem++; + + ymd->year = yr; + + x = _month_date_from_year_day[rem]; + ymd->month = x >> 5; + ymd->day = x & 0x1F; +} + +/** + * Converts a tuple of Year, Month and Day to a Date. + * @param year is a number between 0..MAX_YEAR + * @param month is a number between 0..11 + * @param day is a number between 1..31 + */ +/* static */ TimerGameCalendar::Date TimerGameCalendar::ConvertYMDToDate(TimerGameCalendar::Year year, TimerGameCalendar::Month month, TimerGameCalendar::Day day) +{ + /* Day-offset in a leap year */ + int days = _accum_days_for_month[month] + day - 1; + + /* Account for the missing of the 29th of February in non-leap years */ + if (!TimerGameCalendar::IsLeapYear(year) && days >= ACCUM_MAR) days--; + + return DAYS_TILL(year) + days; +} + +/** + * Checks whether the given year is a leap year or not. + * @param yr The year to check. + * @return True if \c yr is a leap year, otherwise false. + */ +/* static */ bool TimerGameCalendar::IsLeapYear(TimerGameCalendar::Year yr) +{ + return yr % 4 == 0 && (yr % 100 != 0 || yr % 400 == 0); +} + /** * Set the date. * @param date New date @@ -38,7 +157,7 @@ TimerGameCalendar::DateFract TimerGameCalendar::date_fract = {}; TimerGameCalendar::date = date; TimerGameCalendar::date_fract = fract; - ConvertDateToYMD(date, &ymd); + TimerGameCalendar::ConvertDateToYMD(date, &ymd); TimerGameCalendar::year = ymd.year; TimerGameCalendar::month = ymd.month; } @@ -76,8 +195,8 @@ void TimerManager::Elapsed(TimerGameCalendar::TElapsed delta) /* increase day counter */ TimerGameCalendar::date++; - YearMonthDay ymd; - ConvertDateToYMD(TimerGameCalendar::date, &ymd); + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); /* check if we entered a new month? */ bool new_month = ymd.month != TimerGameCalendar::month; @@ -113,7 +232,7 @@ void TimerManager::Elapsed(TimerGameCalendar::TElapsed delta) int days_this_year; TimerGameCalendar::year--; - days_this_year = IsLeapYear(TimerGameCalendar::year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; + days_this_year = TimerGameCalendar::IsLeapYear(TimerGameCalendar::year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; TimerGameCalendar::date -= days_this_year; for (Vehicle *v : Vehicle::Iterate()) v->ShiftDates(-days_this_year); for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year); diff --git a/src/timer/timer_game_calendar.h b/src/timer/timer_game_calendar.h index 133051ae11..2afe179057 100644 --- a/src/timer/timer_game_calendar.h +++ b/src/timer/timer_game_calendar.h @@ -81,6 +81,19 @@ public: using Month = uint8; ///< Type for the month, note: 0 based, i.e. 0 = January, 11 = December. using Day = uint8; ///< Type for the day of the month, note: 1 based, first day of a month is 1. + /** + * Data structure to convert between Date and triplet (year, month, and day). + * @see TimerGameCalendar::ConvertDateToYMD(), TimerGameCalendar::ConvertYMDToDate() + */ + struct YearMonthDay { + Year year; ///< Year (0...) + Month month; ///< Month (0..11) + Day day; ///< Day (1..31) + }; + + static bool IsLeapYear(TimerGameCalendar::Year yr); + static void ConvertDateToYMD(TimerGameCalendar::Date date, YearMonthDay *ymd); + static TimerGameCalendar::Date ConvertYMDToDate(TimerGameCalendar::Year year, TimerGameCalendar::Month month, TimerGameCalendar::Day day); static void SetDate(TimerGameCalendar::Date date, TimerGameCalendar::DateFract fract); static Year year; ///< Current year, starting at 0. diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 38596f742c..cc07a69748 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -17,8 +17,6 @@ #include "rail_gui.h" #include "road.h" #include "road_gui.h" -#include "date_func.h" -#include "timer/timer_game_calendar.h" #include "vehicle_func.h" #include "sound_func.h" #include "terraform_gui.h" @@ -56,6 +54,7 @@ #include "league_base.h" #include "timer/timer.h" #include "timer/timer_window.h" +#include "timer/timer_game_calendar.h" #include "widgets/toolbar_widget.h" @@ -1148,7 +1147,7 @@ void ToggleDirtyBlocks() void SetStartingYear(TimerGameCalendar::Year year) { _settings_game.game_creation.starting_year = Clamp(year, MIN_YEAR, MAX_YEAR); - TimerGameCalendar::Date new_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); + TimerGameCalendar::Date new_date = TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); /* If you open a savegame as scenario there may already be link graphs.*/ LinkGraphSchedule::instance.ShiftDates(new_date - TimerGameCalendar::date); TimerGameCalendar::SetDate(new_date, 0); @@ -2377,7 +2376,7 @@ struct ScenarioEditorToolbarWindow : Window { { switch (widget) { case WID_TE_DATE: - SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1)); break; } } @@ -2406,7 +2405,7 @@ struct ScenarioEditorToolbarWindow : Window { break; case WID_TE_DATE: - SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1)); + SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 0, 1)); *size = GetStringBoundingBox(STR_WHITE_DATE_LONG); break; } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index d2f87e50e8..8d8263eadb 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -25,7 +25,6 @@ #include "group_gui.h" #include "strings_func.h" #include "zoom_func.h" -#include "date_func.h" #include "vehicle_func.h" #include "autoreplace_func.h" #include "autoreplace_gui.h" From ca497ce356858c0926709875db914bef7c041fe3 Mon Sep 17 00:00:00 2001 From: translators Date: Thu, 4 May 2023 18:41:18 +0000 Subject: [PATCH 13/34] Update: Translations from eints japanese: 29 changes by fmang danish: 25 changes by bscargo polish: 29 changes by pAter-exe --- src/lang/danish.txt | 30 +++++++++++++++++++++++++++--- src/lang/japanese.txt | 35 +++++++++++++++++++++++++++++------ src/lang/polish.txt | 40 +++++++++++++++++++++++++++++----------- 3 files changed, 85 insertions(+), 20 deletions(-) diff --git a/src/lang/danish.txt b/src/lang/danish.txt index f530028978..70dfb5b609 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -931,8 +931,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Bevæg h # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opsætning - - +STR_GAME_OPTIONS_TAB_GENERAL :Generel +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Vælg generelle indstillinger +STR_GAME_OPTIONS_TAB_GRAPHICS :Grafik +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Vælg grafikindstillinger +STR_GAME_OPTIONS_TAB_SOUND :Lyd +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Vælg lyd og musik indstillinger + +STR_GAME_OPTIONS_VOLUME :Lydstyrke +STR_GAME_OPTIONS_SFX_VOLUME :Lydeffekter +STR_GAME_OPTIONS_MUSIC_VOLUME :musik + +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Valutaenhed STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Valg af valutaenhed @@ -987,6 +1001,10 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Vælg in # Autosave dropdown ###length 5 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF :Fra +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES :Hvert 10. minut +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES :Hvert 30. minut +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES :Hvert 60. minut +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES :Hvert 120. minut STR_GAME_OPTIONS_LANGUAGE :{BLACK}Sprog STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Vælg sprog til brugerfladen @@ -1712,7 +1730,7 @@ STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Hvor meget huko STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Service intervaller er i procent: {STRING} -STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Vælg om vedligeholdelse bliver udløst af forløbet tid, eller pålideligheden som falder en givet procenttal i forhold til maximum pålideligheden +STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Når den er aktiveret, forsøger køretøjer at servicere, når deres pålidelighed falder med en given procentdel af den maksimale pålidelighed.Hvis f.eks. et køretøjs maksimale pålidelighed er 90 %, og serviceintervallet er 20 %, vil køretøjet forsøge at servicere, når den når 72 % pålidelighed. STR_CONFIG_SETTING_SERVINT_TRAINS :Standard vedligeholdelses interval for tog: {STRING} STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Sæt serviceintervallets standardværdi for nye skinnekøretøjer. @@ -1917,6 +1935,10 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Ingen STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Startværdi for bystørrelsesfaktor: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Gennemsnitlig størrelse af storbyer i forhold til normale byer ved start af spillet +STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL :Opdater distributionsgraf hver {STRING}{NBSP}sekund{P 0:2 "" er} +STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL_HELPTEXT :Tid mellem efterfølgende genberegninger af linkgrafen. Hver genberegning beregner planerne for én komponent af grafen. Det betyder, at en værdi X for denne indstilling ikke betyder, at hele grafen vil blive opdateret hvert X sekund. Kun en komponent vil. Jo kortere du indstiller det, jo mere CPU-tid vil være nødvendigt for at beregne det. Jo længere du indstiller det, jo længere tid vil det tage, før godsfordelingen starter på nye ruter. +STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME :Tag {STRING}{NBSP}sekund{P 0:2 "" er} til genberegning af fordelingsgraf +STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME_HELPTEXT :Tid det tager for hver genberegning af en linkgrafkomponent. Når en genberegning startes, dannes en tråd, som får lov til at køre i dette antal sekunder. Jo kortere du indstiller dette, jo mere sandsynligt er det, at tråden ikke er færdig, når den skal. Så stopper spillet, indtil det er ("lag"). Jo længere du indstiller det, jo længere tid tager det for distributionen at blive opdateret, når ruter ændres. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distributionsmodel for passagerer: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetrisk" betyder, at omtrent det samme antal passagerer vil gå fra en station A til en station B som fra B til A. "Asymmetrisk" betyder, at vilkårlige antal passagerer kan gå i begge retninger. "Manuel" betyder, at der ikke finder nogen automatisk distribution sted for passagerer. @@ -4573,6 +4595,7 @@ STR_AI_CONFIG_RANDOM_AI :Tilfældig comp STR_AI_CONFIG_NONE :(ingen) STR_AI_CONFIG_NAME_VERSION :{STRING} {YELLOW}v{NUM} STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maksimalt antal modstandere: {ORANGE}{COMMA} +STR_AI_CONFIG_COMPETITORS_INTERVAL :{LTBLUE}Interval mellem konkurrenternes start: {ORANGE}{COMMA} minut{P "" er} STR_AI_CONFIG_MOVE_UP :{BLACK}Flyt op STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Flyt valgte computerspiller op i listen @@ -5087,6 +5110,7 @@ STR_ERROR_NO_BUOY :{WHITE}Der er i STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kan ikke lave køreplan for transportmiddel... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Transportmidler kan kun vente ved stationer. STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}Dette transportmiddel stopper ikke ved denne station. +STR_ERROR_TIMETABLE_INCOMPLETE :{WHITE}... tidsplanen er ufuldstændig # Sign related errors STR_ERROR_TOO_MANY_SIGNS :{WHITE}... for mange skilte diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index ea444f0a7f..73ce8f4e6b 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -195,6 +195,7 @@ STR_UNITS_VELOCITY_IMPERIAL :{COMMA}mph STR_UNITS_VELOCITY_METRIC :{COMMA}km/h STR_UNITS_VELOCITY_SI :{COMMA}m/s STR_UNITS_VELOCITY_GAMEUNITS :{DECIMAL}{NBSP}タイル/日 +STR_UNITS_VELOCITY_KNOTS :{COMMA}{NBSP}ノット STR_UNITS_POWER_IMPERIAL :{COMMA}英馬力 STR_UNITS_POWER_METRIC :{COMMA}仏馬力 @@ -344,8 +345,8 @@ STR_GOTO_ORDER_VIEW_TOOLTIP :{BLACK}指令 STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}ゲームをポーズします STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}ゲーム進行速度を早くします STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}ゲームオプションの設定画面を開きます -STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}ゲームのセーブ、中断、OpenTTDの終了ができます -STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}地図の表示、ビューポートの表示、標識のリストの表示ができます +STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}ゲームのセーブ、ロード、中断、OpenTTDの終了ができます +STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}地図の表示、ビューポートの表示、貨物流通、標識のリストの表示ができます STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}街の一覧を表示します STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}助成金一覧を表示します STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}社有の停留施設の一覧を表示します @@ -355,7 +356,7 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}ゲー STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}ゲームの目標一覧を表示します STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}さまざまなグラフを表示します STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}会社の業務成績表を表示します -STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}新たな産業の開設に出資します +STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}産業を調査、及び産業の開設に出資します STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}社有の列車一覧とそのグループを表示します。Ctrl+クリックで一覧のみ表示します STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}社有の車両一覧とそのグループを表示します。Ctrl+クリックで一覧のみ表示します STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}社有の船舶一覧とそのグループを表示します。Ctrl+クリックで一覧のみ表示します @@ -430,7 +431,7 @@ STR_FILE_MENU_EXIT :OpenTTDを終 ###length 4 STR_MAP_MENU_MAP_OF_WORLD :地図 STR_MAP_MENU_EXTRA_VIEWPORT :ビューポートを開く -STR_MAP_MENU_LINGRAPH_LEGEND :貨物輸送履歴 +STR_MAP_MENU_LINGRAPH_LEGEND :貨物流通履歴 STR_MAP_MENU_SIGN_LIST :標識リスト # Town menu @@ -930,8 +931,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}この # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}ゲーム設定 +STR_GAME_OPTIONS_TAB_GENERAL :一般 +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}一般設定を開きます +STR_GAME_OPTIONS_TAB_GRAPHICS :グラフィック +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}グラフィック設定を開きます +STR_GAME_OPTIONS_TAB_SOUND :サウンド +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}サウンドと音楽の設定を開きます +STR_GAME_OPTIONS_VOLUME :音量 +STR_GAME_OPTIONS_SFX_VOLUME :効果音 +STR_GAME_OPTIONS_MUSIC_VOLUME :音楽 +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}通貨単位 STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}通貨単位の選択 @@ -986,6 +1001,10 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}自動 # Autosave dropdown ###length 5 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF :しない +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES :10分毎 +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES :30分毎 +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES :60分毎 +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES :120分毎 STR_GAME_OPTIONS_LANGUAGE :{BLACK}言語 STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}ゲームの言語を選択します @@ -1941,13 +1960,15 @@ STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :この値を100 STR_CONFIG_SETTING_SHORT_PATH_SATURATION :高収容力経路より速達経路を優先飽和: {STRING} STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :二つの停留施設間を結ぶ経路が複数存在することは往々にしてあります。そのような場合、貨物分配アルゴリズムは最初に最短となる経路を飽和するまで使用し、次いで2番目の最短経路を使用するというように埋めていきます。飽和したかどうかは、推定収容力、輸送計画によって判断されます。すべての経路を飽和してもまだ需要を満たせない場合、高容量な経路を優先しつつ、すべての経路に負荷を掛けます。しかしほとんどの場合、アルゴリズムは経路の輸送力を正確に見積もることができません。この設定では、高収容力の路線を使用し始める前にどの程度最短経路を飽和するかを設定します。収容力より需要が上回ると推定される時には、停留施設が混み合うのを避けるために100%未満に設定して下さい。 -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :速度単位: {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :速度単位(陸地): {STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_NAUTICAL :速度単位(海事): {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :ゲーム中の速度をいずれの単位系で表すか決定します ###length 5 STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL :ヤード・ポンド法 (マイル時(mph)) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC :メートル法 (km/h) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :国際単位系 (m/s) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS :ゲーム内単位(タイル/日) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_KNOTS :ノット STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :動力単位: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT :ゲーム中の動力(仕事率、主に輸送機器の出力表記)をいずれの単位系で表すか決定します @@ -4568,6 +4589,7 @@ STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}このAI STR_AI_CONFIG_HUMAN_PLAYER :人間のプレーヤー STR_AI_CONFIG_RANDOM_AI :ランダムなAI STR_AI_CONFIG_NONE :(なし) +STR_AI_CONFIG_NAME_VERSION :{STRING} {YELLOW}v{NUM} STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}最大競争会社数: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}上に移動 @@ -4581,7 +4603,7 @@ STR_AI_CONFIG_AI :{SILVER}AI STR_AI_CONFIG_CHANGE_AI :{BLACK}AIを選択 STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}ゲームスクリプトを選択 -STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}他のスクリプトをロードします +STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}他のスクリプトをロードします。Ctrl+クリックで全ての利用可能バージョンを表示します STR_AI_CONFIG_CONFIGURE :{BLACK}設定 STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}スクリプトのパラメータを設定します @@ -5083,6 +5105,7 @@ STR_ERROR_NO_BUOY :{WHITE}ブイ STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}この輸送機器にダイヤを設定できません STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}輸送機器は停留施設でのみ待機できます STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}この輸送機器はこの停留施設には停まれません +STR_ERROR_TIMETABLE_INCOMPLETE :{WHITE}…ダイヤが未完成です # Sign related errors STR_ERROR_TOO_MANY_SIGNS :{WHITE}標識が多すぎます diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 2de45246ad..f91343c51a 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -1047,7 +1047,7 @@ STR_PERFORMANCE_DETAIL_LOAN_TOOLTIP :{BLACK}Wielkoś STR_PERFORMANCE_DETAIL_TOTAL_TOOLTIP :{BLACK}Suma przyznanych punktów # Music window -STR_MUSIC_JAZZ_JUKEBOX_CAPTION :{WHITE}Jazz Jukebox +STR_MUSIC_JAZZ_JUKEBOX_CAPTION :{WHITE}Szafa Grająca STR_MUSIC_PLAYLIST_ALL :{TINY_FONT}{BLACK}Wszystko STR_MUSIC_PLAYLIST_OLD_STYLE :{TINY_FONT}{BLACK}Stary styl STR_MUSIC_PLAYLIST_NEW_STYLE :{TINY_FONT}{BLACK}Nowy styl @@ -1060,7 +1060,7 @@ STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKG STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Brak dostępnej muzyki -STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" +STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}„{STRING}” STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Ścieżka STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Tytuł STR_MUSIC_SHUFFLE :{TINY_FONT}{BLACK}Losowo @@ -1070,20 +1070,20 @@ STR_MUSIC_TOOLTIP_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Przejdź STR_MUSIC_TOOLTIP_STOP_PLAYING_MUSIC :{BLACK}Zatrzymaj muzykę STR_MUSIC_TOOLTIP_START_PLAYING_MUSIC :{BLACK}Odtwarzaj muzykę STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Przesuń suwaki żeby ustawić głośność dźwięków i muzyki -STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Wybierz program 'Wszystko' -STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC :{BLACK}Wybierz program 'Stary styl' -STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC :{BLACK}Wybierz program 'Nowy styl' -STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE :{BLACK}Wybierz program 'Ezy Street' -STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Wybierz program 'Własny 1' (definiowany) -STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Wybierz program 'Własny 2' (definiowany) -STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Losowe odtwarzanie wł./wył. +STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Wybierz program „Wszystko” +STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC :{BLACK}Wybierz program „Stary styl” +STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC :{BLACK}Wybierz program „Nowy styl” +STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE :{BLACK}Wybierz program „Ezy Street” +STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Wybierz program „Własny 1” (zdefiniowany przez użytkownika) +STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Wybierz program „Własny 2” (zdefiniowany przez użytkownika) +STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Włącz/wyłącz losowe odtwarzanie STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Pokaż okno wyboru ścieżek # Playlist window -STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Program muzyczny - '{STRING}' +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Program muzyczny - „{STRING}” STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Wykaz ścieżek -STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programuj - '{STRING}' +STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - „{STRING}” STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Wyczyść STR_PLAYLIST_CHANGE_SET :{BLACK}Zmień zestaw STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Wyczyść obecny program (tylko Wlasny1 lub Wlasny2) @@ -1311,8 +1311,22 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopiuj p # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcje gry +STR_GAME_OPTIONS_TAB_GENERAL :Ogólne +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}Wybierz opcje ogólne +STR_GAME_OPTIONS_TAB_GRAPHICS :Grafika +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}Wybierz opcje grafiki +STR_GAME_OPTIONS_TAB_SOUND :Dźwięk +STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}Wybierz opcje dźwięku i muzyki +STR_GAME_OPTIONS_VOLUME :Głośność +STR_GAME_OPTIONS_SFX_VOLUME :Efekty dźwiękowe +STR_GAME_OPTIONS_MUSIC_VOLUME :Muzyka +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Waluta STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Wybór waluty @@ -1367,6 +1381,10 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Częstot # Autosave dropdown ###length 5 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF :Wył. +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES :Co 10 minut +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES :Co 30 minut +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES :Co 60 minut +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES :Co 120 minut STR_GAME_OPTIONS_LANGUAGE :{BLACK}Język STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Wybierz język interfejsu From 4a5e413a6c9eec57a05cdfc7e05c5cd21453e9b2 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 23 Apr 2023 21:22:17 +0100 Subject: [PATCH 14/34] Cleanup: Remove unnecessary VehicleRandomBits() Simple Random() assignment to byte does the same. --- src/aircraft_cmd.cpp | 6 +++--- src/articulated_vehicles.cpp | 3 ++- src/roadveh_cmd.cpp | 2 +- src/ship_cmd.cpp | 2 +- src/train_cmd.cpp | 6 +++--- src/vehicle.cpp | 9 --------- src/vehicle_func.h | 1 - 7 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 2b867caf7e..9f144be413 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -344,8 +344,8 @@ CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine * v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY); u->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY); - v->random_bits = VehicleRandomBits(); - u->random_bits = VehicleRandomBits(); + v->random_bits = Random(); + u->random_bits = Random(); v->vehicle_flags = 0; if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); @@ -375,7 +375,7 @@ CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine * w->spritenum = 0xFF; w->subtype = AIR_ROTOR; w->sprite_cache.sprite_seq.Set(SPR_ROTOR_STOPPED); - w->random_bits = VehicleRandomBits(); + w->random_bits = Random(); /* Use rotor's air.state to store the rotor animation frame */ w->state = HRS_ROTOR_STOPPED; w->UpdateDeltaXY(); diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 2fdb07a453..b3aa98fe0b 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -8,6 +8,7 @@ /** @file articulated_vehicles.cpp Implementation of articulated vehicles. */ #include "stdafx.h" +#include "core/random_func.hpp" #include "train.h" #include "roadveh.h" #include "vehicle_func.h" @@ -405,7 +406,7 @@ void AddArticulatedParts(Vehicle *first) v->engine_type = engine_type; v->value = 0; v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY); - v->random_bits = VehicleRandomBits(); + v->random_bits = Random(); if (flip_image) v->spritenum++; diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 62550d847e..af796f5330 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -303,7 +303,7 @@ CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engin v->build_year = TimerGameCalendar::year; v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY); - v->random_bits = VehicleRandomBits(); + v->random_bits = Random(); v->SetFrontEngine(); v->roadtype = rt; diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index a7cad340c4..8662f4ac78 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -905,7 +905,7 @@ CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, V v->date_of_last_service = TimerGameCalendar::date; v->build_year = TimerGameCalendar::year; v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY); - v->random_bits = VehicleRandomBits(); + v->random_bits = Random(); v->UpdateCache(); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 900f2fa9b6..2ab7e7c991 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -656,7 +656,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const v->date_of_last_service = TimerGameCalendar::date; v->build_year = TimerGameCalendar::year; v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY); - v->random_bits = VehicleRandomBits(); + v->random_bits = Random(); v->group_id = DEFAULT_GROUP; @@ -721,7 +721,7 @@ static void AddRearEngineToMultiheadedTrain(Train *v) u->date_of_last_service = v->date_of_last_service; u->build_year = v->build_year; u->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY); - u->random_bits = VehicleRandomBits(); + u->random_bits = Random(); v->SetMultiheaded(); u->SetMultiheaded(); v->SetNext(u); @@ -786,7 +786,7 @@ CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engin v->date_of_last_service = TimerGameCalendar::date; v->build_year = TimerGameCalendar::year; v->sprite_cache.sprite_seq.Set(SPR_IMG_QUERY); - v->random_bits = VehicleRandomBits(); + v->random_bits = Random(); if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); v->SetServiceIntervalIsPercent(Company::Get(_current_company)->settings.vehicle.servint_ispercent); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 8d8263eadb..96e9871f4d 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -359,15 +359,6 @@ Vehicle::Vehicle(VehicleType type) this->last_loading_station = INVALID_STATION; } -/** - * Get a value for a vehicle's random_bits. - * @return A random value from 0 to 255. - */ -byte VehicleRandomBits() -{ - return GB(Random(), 0, 8); -} - /* Size of the hash, 6 = 64 x 64, 7 = 128 x 128. Larger sizes will (in theory) reduce hash * lookup times at the expense of memory usage. */ const int HASH_BITS = 7; diff --git a/src/vehicle_func.h b/src/vehicle_func.h index d88ff74117..06001f4f07 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -50,7 +50,6 @@ uint8 CalcPercentVehicleFilled(const Vehicle *v, StringID *colour); void VehicleLengthChanged(const Vehicle *u); -byte VehicleRandomBits(); void ResetVehicleHash(); void ResetVehicleColourMap(); From 7ccdefa1c18b3ed18547d453f9c8f7de02bb8eb5 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 23 Apr 2023 21:21:17 +0100 Subject: [PATCH 15/34] Change: Increase vehicle random data from 8 to 16 bits. --- src/newgrf_engine.cpp | 4 ++-- src/saveload/saveload.h | 2 ++ src/saveload/vehicle_sl.cpp | 3 ++- src/vehicle_base.h | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 63a195f52f..1eae6e36d5 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1207,7 +1207,7 @@ int GetEngineProperty(EngineID engine, PropertyID property, int orig_value, cons } -static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first) +static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, uint16_t base_random_bits, bool first) { /* We can't trigger a non-existent vehicle... */ assert(v != nullptr); @@ -1223,7 +1223,7 @@ static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_rando v->waiting_triggers = object.GetRemainingTriggers(); /* Rerandomise bits. Scopes other than SELF are invalid for rerandomisation. For bug-to-bug-compatibility with TTDP we ignore the scope. */ - byte new_random_bits = Random(); + uint16_t new_random_bits = Random(); uint32 reseed = object.GetReseedSum(); v->random_bits &= ~reseed; v->random_bits |= (first ? new_random_bits : base_random_bits) & reseed; diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index ba5d5480fe..f95ec57150 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -353,6 +353,8 @@ enum SaveLoadVersion : uint16 { SLV_LINKGRAPH_SECONDS, ///< 308 PR#10610 Store linkgraph update intervals in seconds instead of days. SLV_AI_START_DATE, ///< 309 PR#10653 Removal of individual AI start dates and added a generic one. + SLV_EXTEND_VEHICLE_RANDOM, ///< 310 PR#10701 Extend vehicle random bits. + SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index e0c217d762..13c79438f1 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -704,7 +704,8 @@ public: SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SLV_65), SLE_CONDVAR(Vehicle, value, SLE_INT64, SLV_65, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, SLV_2, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, random_bits, SLE_FILE_U8 | SLE_VAR_U16, SLV_2, SLV_EXTEND_VEHICLE_RANDOM), + SLE_CONDVAR(Vehicle, random_bits, SLE_UINT16, SLV_EXTEND_VEHICLE_RANDOM, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, SLV_2, SL_MAX_VERSION), SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, SLV_2, SL_MAX_VERSION), diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 44d440822b..7323508294 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -328,7 +328,7 @@ public: uint32 motion_counter; ///< counter to occasionally play a vehicle sound. byte progress; ///< The percentage (if divided by 256) this vehicle already crossed the tile unit. - byte random_bits; ///< Bits used for determining which randomized variational spritegroups to use when drawing. + uint16_t random_bits; ///< Bits used for randomized variational spritegroups. byte waiting_triggers; ///< Triggers to be yet matched before rerandomizing the random bits. StationID last_station_visited; ///< The last station we stopped at. From 8d501f2db13cebdf006ffe3bb199ed1b5d2a6ade Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Thu, 4 May 2023 21:45:13 +0100 Subject: [PATCH 16/34] Fix #10741: Rail platforms left partially reserved after train crash (#10751) --- src/train_cmd.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 2ab7e7c991..2880c60999 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3550,6 +3550,20 @@ static Vehicle *CollectTrackbitsFromCrashedVehiclesEnum(Vehicle *v, void *data) return nullptr; } +static bool IsRailStationPlatformOccupied(TileIndex tile) +{ + TileIndexDiff delta = (GetRailStationAxis(tile) == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); + + for (TileIndex t = tile; IsCompatibleTrainStationTile(t, tile); t -= delta) { + if (HasVehicleOnPos(t, nullptr, &TrainOnTileEnum)) return true; + } + for (TileIndex t = tile + delta; IsCompatibleTrainStationTile(t, tile); t += delta) { + if (HasVehicleOnPos(t, nullptr, &TrainOnTileEnum)) return true; + } + + return false; +} + /** * Deletes/Clears the last wagon of a crashed train. It takes the engine of the * train, then goes to the last wagon and deletes that. Each call to this function @@ -3608,6 +3622,13 @@ static void DeleteLastWagon(Train *v) /* check if the wagon was on a road/rail-crossing */ if (IsLevelCrossingTile(tile)) UpdateLevelCrossing(tile); + if (IsRailStationTile(tile)) { + bool occupied = IsRailStationPlatformOccupied(tile); + DiagDirection dir = AxisToDiagDir(GetRailStationAxis(tile)); + SetRailStationPlatformReservation(tile, dir, occupied); + SetRailStationPlatformReservation(tile, ReverseDiagDir(dir), occupied); + } + /* Update signals */ if (IsTileType(tile, MP_TUNNELBRIDGE) || IsRailDepotTile(tile)) { UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, owner); From c6c3d0e6face26639dda02815cf0599b60d0602b Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 4 May 2023 22:46:02 +0200 Subject: [PATCH 17/34] Fix: no_http_content_downloads and use_relay_service as private settings (#10762) Basically, we don't need to know those values when people send in crash reports. --- src/settings.cpp | 41 +++++++++++++++++-- .../settings/network_private_settings.ini | 27 +++++++++++- src/table/settings/network_settings.ini | 20 --------- 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index a71846e58a..6dfd8e240d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -155,10 +155,11 @@ public: * location. These versions assist with situations like that. */ enum IniFileVersion : uint32 { - IFV_0, ///< 0 All versions prior to introduction. - IFV_PRIVATE_SECRETS, ///< 1 PR#9298 Moving of settings from openttd.cfg to private.cfg / secrets.cfg. - IFV_GAME_TYPE, ///< 2 PR#9515 Convert server_advertise to server_game_type. - IFV_LINKGRAPH_SECONDS, ///< 3 PR#10610 Store linkgraph update intervals in seconds instead of days. + IFV_0, ///< 0 All versions prior to introduction. + IFV_PRIVATE_SECRETS, ///< 1 PR#9298 Moving of settings from openttd.cfg to private.cfg / secrets.cfg. + IFV_GAME_TYPE, ///< 2 PR#9515 Convert server_advertise to server_game_type. + IFV_LINKGRAPH_SECONDS, ///< 3 PR#10610 Store linkgraph update intervals in seconds instead of days. + IFV_NETWORK_PRIVATE_SETTINGS, ///< 4 PR#10762 Move no_http_content_downloads / use_relay_service to private settings. IFV_MAX_VERSION, ///< Highest possible ini-file version. }; @@ -1243,6 +1244,31 @@ void LoadFromConfig(bool startup) _settings_newgame.linkgraph.recalc_time *= SECONDS_PER_DAY; } + if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) { + IniGroup *network = generic_ini.GetGroup("network", false); + if (network != nullptr) { + IniItem *no_http_content_downloads = network->GetItem("no_http_content_downloads", false); + if (no_http_content_downloads != nullptr) { + if (no_http_content_downloads->value == "true") { + _settings_client.network.no_http_content_downloads = true; + } else if (no_http_content_downloads->value == "false") { + _settings_client.network.no_http_content_downloads = false; + } + } + + IniItem *use_relay_service = network->GetItem("use_relay_service", false); + if (use_relay_service != nullptr) { + if (use_relay_service->value == "never") { + _settings_client.network.use_relay_service = UseRelayService::URS_NEVER; + } else if (use_relay_service->value == "ask") { + _settings_client.network.use_relay_service = UseRelayService::URS_ASK; + } else if (use_relay_service->value == "allow") { + _settings_client.network.use_relay_service = UseRelayService::URS_ALLOW; + } + } + } + } + _grfconfig_newgame = GRFLoadConfig(generic_ini, "newgrf", false); _grfconfig_static = GRFLoadConfig(generic_ini, "newgrf-static", true); AILoadConfig(generic_ini, "ai_players"); @@ -1304,6 +1330,13 @@ void SaveToConfig() network->RemoveItem("server_advertise"); } } + if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) { + IniGroup *network = generic_ini.GetGroup("network", false); + if (network != nullptr) { + network->RemoveItem("no_http_content_downloads"); + network->RemoveItem("use_relay_service"); + } + } HandleSettingDescs(generic_ini, private_ini, secrets_ini, IniSaveSettings, IniSaveSettingList); GRFSaveConfig(generic_ini, "newgrf", _grfconfig_newgame); diff --git a/src/table/settings/network_private_settings.ini b/src/table/settings/network_private_settings.ini index cae43330fd..4bd478882b 100644 --- a/src/table/settings/network_private_settings.ini +++ b/src/table/settings/network_private_settings.ini @@ -7,13 +7,19 @@ ; Network settings as stored in the private configuration file ("private.cfg"). [pre-amble] +static constexpr std::initializer_list _use_relay_service{"never", "ask", "allow"}; + static const SettingVariant _network_private_settings_table[] = { [post-amble] }; [templates] -SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $def, $length, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), +SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup), [validation] +SDTC_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); +SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size"); [defaults] flags = SF_NONE @@ -66,3 +72,22 @@ length = 0 flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC def = """" cat = SC_EXPERT + +[SDTC_BOOL] +var = network.no_http_content_downloads +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +cat = SC_EXPERT + +[SDTC_OMANY] +var = network.use_relay_service +type = SLE_UINT8 +flags = SF_GUI_DROPDOWN | SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = URS_ASK +min = URS_NO +max = URS_ALLOW +full = _use_relay_service +str = STR_CONFIG_SETTING_USE_RELAY_SERVICE +strhelp = STR_CONFIG_SETTING_USE_RELAY_SERVICE_HELPTEXT +strval = STR_CONFIG_SETTING_USE_RELAY_SERVICE_NEVER +cat = SC_BASIC diff --git a/src/table/settings/network_settings.ini b/src/table/settings/network_settings.ini index d43cbcbd40..860eb26cec 100644 --- a/src/table/settings/network_settings.ini +++ b/src/table/settings/network_settings.ini @@ -10,7 +10,6 @@ static void UpdateClientConfigValues(); static constexpr std::initializer_list _server_game_type{"local", "public", "invite-only"}; -static constexpr std::initializer_list _use_relay_service{"never", "ask", "allow"}; static const SettingVariant _network_settings_table[] = { [post-amble] @@ -246,22 +245,3 @@ var = network.reload_cfg flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY def = false cat = SC_EXPERT - -[SDTC_BOOL] -var = network.no_http_content_downloads -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = false -cat = SC_EXPERT - -[SDTC_OMANY] -var = network.use_relay_service -type = SLE_UINT8 -flags = SF_GUI_DROPDOWN | SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC -def = URS_ASK -min = URS_NO -max = URS_ALLOW -full = _use_relay_service -str = STR_CONFIG_SETTING_USE_RELAY_SERVICE -strhelp = STR_CONFIG_SETTING_USE_RELAY_SERVICE_HELPTEXT -strval = STR_CONFIG_SETTING_USE_RELAY_SERVICE_NEVER -cat = SC_BASIC From 51c6b8c1e4b1f4797e2c1767c96925c58fafd498 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 29 Apr 2023 13:11:45 +0200 Subject: [PATCH 18/34] Codechange: use fmt::format_to for gamelog message creation over seprintf --- src/crashlog.cpp | 4 +- src/gamelog.cpp | 98 +++++++++++++++++++++++------------------------- src/gamelog.h | 2 +- 3 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/crashlog.cpp b/src/crashlog.cpp index f6a34a6328..6ee4c83505 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -300,8 +300,8 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const */ char *CrashLog::LogGamelog(char *buffer, const char *last) const { - _gamelog.Print([&buffer, last](const char *s) { - buffer += seprintf(buffer, last, "%s\n", s); + _gamelog.Print([&buffer, last](const std::string &s) { + buffer += seprintf(buffer, last, "%s\n", s.c_str()); }); return buffer + seprintf(buffer, last, "\n"); } diff --git a/src/gamelog.cpp b/src/gamelog.cpp index 5ce866e32d..8477ab90cd 100644 --- a/src/gamelog.cpp +++ b/src/gamelog.cpp @@ -114,36 +114,34 @@ void Gamelog::Reset() } /** - * Prints GRF ID, checksum and filename if found - * @param buf The location in the buffer to draw + * Adds the GRF ID, checksum and filename if found to the output iterator + * @param outputIterator The iterator to add the GRF info to. * @param last The end of the buffer * @param grfid GRF ID * @param md5sum array of md5sum to print, if known * @param gc GrfConfig, if known - * @return The buffer location. */ -static char *PrintGrfInfo(char *buf, const char *last, uint grfid, const uint8 *md5sum, const GRFConfig *gc) +template +static void AddGrfInfo(T &outputIterator, uint grfid, const uint8 *md5sum, const GRFConfig *gc) { - char txt[40]; - if (md5sum != nullptr) { + char txt[40]; md5sumToString(txt, lastof(txt), md5sum); - buf += seprintf(buf, last, "GRF ID %08X, checksum %s", BSWAP32(grfid), txt); + fmt::format_to(outputIterator, "GRF ID {:08X}, checksum {}", BSWAP32(grfid), txt); } else { - buf += seprintf(buf, last, "GRF ID %08X", BSWAP32(grfid)); + fmt::format_to(outputIterator, "GRF ID {:08X}", BSWAP32(grfid)); } if (gc != nullptr) { - buf += seprintf(buf, last, ", filename: %s (md5sum matches)", gc->filename); + fmt::format_to(outputIterator, ", filename: {} (md5sum matches)", gc->filename); } else { gc = FindGRFConfig(grfid, FGCM_ANY); if (gc != nullptr) { - buf += seprintf(buf, last, ", filename: %s (matches GRFID only)", gc->filename); + fmt::format_to(outputIterator, ", filename: {} (matches GRFID only)", gc->filename); } else { - buf += seprintf(buf, last, ", unknown GRF"); + fmt::format_to(outputIterator, ", unknown GRF"); } } - return buf; } @@ -180,9 +178,8 @@ typedef SmallMap GrfIDMapping; * Prints active gamelog * @param proc the procedure to draw with */ -void Gamelog::Print(std::function proc) +void Gamelog::Print(std::function proc) { - char buffer[1024]; GrfIDMapping grf_names; proc("---- gamelog start ----"); @@ -190,58 +187,57 @@ void Gamelog::Print(std::function proc) for (const LoggedAction &la : this->data->action) { assert((uint)la.at < GLAT_END); - seprintf(buffer, lastof(buffer), "Tick %u: %s", (uint)la.tick, la_text[(uint)la.at]); - proc(buffer); + proc(fmt::format("Tick {}: {}", la.tick, la_text[la.at])); for (const LoggedChange &lc : la.change) { - char *buf = buffer; + std::string message; + auto outputIterator = std::back_inserter(message); switch (lc.ct) { default: NOT_REACHED(); case GLCT_MODE: /* Changing landscape, or going from scenario editor to game or back. */ - buf += seprintf(buf, lastof(buffer), "New game mode: %u landscape: %u", - (uint)lc.mode.mode, (uint)lc.mode.landscape); + fmt::format_to(outputIterator, "New game mode: {} landscape: {}", lc.mode.mode, lc.mode.landscape); break; case GLCT_REVISION: /* The game was loaded in a diffferent version than before. */ - buf += seprintf(buf, lastof(buffer), "Revision text changed to %s, savegame version %u, ", + fmt::format_to(outputIterator, "Revision text changed to {}, savegame version {}, ", lc.revision.text, lc.revision.slver); switch (lc.revision.modified) { - case 0: buf += seprintf(buf, lastof(buffer), "not "); break; - case 1: buf += seprintf(buf, lastof(buffer), "maybe "); break; + case 0: message += "not "; break; + case 1: message += "maybe "; break; default: break; } - buf += seprintf(buf, lastof(buffer), "modified, _openttd_newgrf_version = 0x%08x", lc.revision.newgrf); + fmt::format_to(outputIterator, "modified, _openttd_newgrf_version = 0x{:08x}", lc.revision.newgrf); break; case GLCT_OLDVER: /* The game was loaded from before 0.7.0-beta1. */ - buf += seprintf(buf, lastof(buffer), "Conversion from "); + message += "Conversion from "; switch (lc.oldver.type) { default: NOT_REACHED(); case SGT_OTTD: - buf += seprintf(buf, lastof(buffer), "OTTD savegame without gamelog: version %u, %u", + fmt::format_to(outputIterator, "OTTD savegame without gamelog: version {}, {}", GB(lc.oldver.version, 8, 16), GB(lc.oldver.version, 0, 8)); break; case SGT_TTO: - buf += seprintf(buf, lastof(buffer), "TTO savegame"); + message += "TTO savegame"; break; case SGT_TTD: - buf += seprintf(buf, lastof(buffer), "TTD savegame"); + message += "TTD savegame"; break; case SGT_TTDP1: case SGT_TTDP2: - buf += seprintf(buf, lastof(buffer), "TTDP savegame, %s format", + fmt::format_to(outputIterator, "TTDP savegame, {} format", lc.oldver.type == SGT_TTDP1 ? "old" : "new"); if (lc.oldver.version != 0) { - buf += seprintf(buf, lastof(buffer), ", TTDP version %u.%u.%u.%u", + fmt::format_to(outputIterator, ", TTDP version {}.{}.{}.{}", GB(lc.oldver.version, 24, 8), GB(lc.oldver.version, 20, 4), GB(lc.oldver.version, 16, 4), GB(lc.oldver.version, 0, 16)); } @@ -251,16 +247,16 @@ void Gamelog::Print(std::function proc) case GLCT_SETTING: /* A setting with the SF_NO_NETWORK flag got changed; these settings usually affect NewGRFs, such as road side or wagon speed limits. */ - buf += seprintf(buf, lastof(buffer), "Setting changed: %s : %d -> %d", lc.setting.name, lc.setting.oldval, lc.setting.newval); + fmt::format_to(outputIterator, "Setting changed: {} : {} -> {}", lc.setting.name, lc.setting.oldval, lc.setting.newval); break; case GLCT_GRFADD: { /* A NewGRF got added to the game, either at the start of the game (never an issue), or later on when it could be an issue. */ const GRFConfig *gc = FindGRFConfig(lc.grfadd.grfid, FGCM_EXACT, lc.grfadd.md5sum); - buf += seprintf(buf, lastof(buffer), "Added NewGRF: "); - buf = PrintGrfInfo(buf, lastof(buffer), lc.grfadd.grfid, lc.grfadd.md5sum, gc); + message += "Added NewGRF: "; + AddGrfInfo(outputIterator, lc.grfadd.grfid, lc.grfadd.md5sum, gc); GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); - if (gm != grf_names.End() && !gm->second.was_missing) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was already added!"); + if (gm != grf_names.End() && !gm->second.was_missing) message += ". Gamelog inconsistency: GrfID was already added!"; grf_names[lc.grfadd.grfid] = gc; break; } @@ -268,10 +264,10 @@ void Gamelog::Print(std::function proc) case GLCT_GRFREM: { /* A NewGRF got removed from the game, either manually or by it missing when loading the game. */ GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); - buf += seprintf(buf, lastof(buffer), la.at == GLAT_LOAD ? "Missing NewGRF: " : "Removed NewGRF: "); - buf = PrintGrfInfo(buf, lastof(buffer), lc.grfrem.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); + message += la.at == GLAT_LOAD ? "Missing NewGRF: " : "Removed NewGRF: "; + AddGrfInfo(outputIterator, lc.grfrem.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); if (gm == grf_names.End()) { - buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); + message += ". Gamelog inconsistency: GrfID was never added!"; } else { if (la.at == GLAT_LOAD) { /* Missing grfs on load are not removed from the configuration */ @@ -286,9 +282,9 @@ void Gamelog::Print(std::function proc) case GLCT_GRFCOMPAT: { /* Another version of the same NewGRF got loaded. */ const GRFConfig *gc = FindGRFConfig(lc.grfadd.grfid, FGCM_EXACT, lc.grfadd.md5sum); - buf += seprintf(buf, lastof(buffer), "Compatible NewGRF loaded: "); - buf = PrintGrfInfo(buf, lastof(buffer), lc.grfcompat.grfid, lc.grfcompat.md5sum, gc); - if (!grf_names.Contains(lc.grfcompat.grfid)) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); + message += "Compatible NewGRF loaded: "; + AddGrfInfo(outputIterator, lc.grfcompat.grfid, lc.grfcompat.md5sum, gc); + if (!grf_names.Contains(lc.grfcompat.grfid)) message += ". Gamelog inconsistency: GrfID was never added!"; grf_names[lc.grfcompat.grfid] = gc; break; } @@ -296,19 +292,19 @@ void Gamelog::Print(std::function proc) case GLCT_GRFPARAM: { /* A parameter of a NewGRF got changed after the game was started. */ GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); - buf += seprintf(buf, lastof(buffer), "GRF parameter changed: "); - buf = PrintGrfInfo(buf, lastof(buffer), lc.grfparam.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); - if (gm == grf_names.End()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); + message += "GRF parameter changed: "; + AddGrfInfo(outputIterator, lc.grfparam.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); + if (gm == grf_names.End()) message += ". Gamelog inconsistency: GrfID was never added!"; break; } case GLCT_GRFMOVE: { /* The order of NewGRFs got changed, which might cause some other NewGRFs to behave differently. */ GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); - buf += seprintf(buf, lastof(buffer), "GRF order changed: %08X moved %d places %s", + fmt::format_to(outputIterator, "GRF order changed: {:08X} moved {} places {}", BSWAP32(lc.grfmove.grfid), abs(lc.grfmove.offset), lc.grfmove.offset >= 0 ? "down" : "up" ); - buf = PrintGrfInfo(buf, lastof(buffer), lc.grfmove.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); - if (gm == grf_names.End()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); + AddGrfInfo(outputIterator, lc.grfmove.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); + if (gm == grf_names.End()) message += ". Gamelog inconsistency: GrfID was never added!"; break; } @@ -317,9 +313,9 @@ void Gamelog::Print(std::function proc) GrfIDMapping::Pair *gm = grf_names.Find(lc.grfrem.grfid); assert(lc.grfbug.bug == GBUG_VEH_LENGTH); - buf += seprintf(buf, lastof(buffer), "Rail vehicle changes length outside a depot: GRF ID %08X, internal ID 0x%X", BSWAP32(lc.grfbug.grfid), (uint)lc.grfbug.data); - buf = PrintGrfInfo(buf, lastof(buffer), lc.grfbug.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); - if (gm == grf_names.End()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); + fmt::format_to(outputIterator, "Rail vehicle changes length outside a depot: GRF ID {:08X}, internal ID 0x{:X}", BSWAP32(lc.grfbug.grfid), (uint)lc.grfbug.data); + AddGrfInfo(outputIterator, lc.grfbug.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); + if (gm == grf_names.End()) message += ". Gamelog inconsistency: GrfID was never added!"; break; } @@ -329,7 +325,7 @@ void Gamelog::Print(std::function proc) break; } - proc(buffer); + proc(message); } } @@ -340,7 +336,7 @@ void Gamelog::Print(std::function proc) /** Print the gamelog data to the console. */ void Gamelog::PrintConsole() { - this->Print([](const char *s) { + this->Print([](const std::string &s) { IConsolePrint(CC_WARNING, s); }); } @@ -353,7 +349,7 @@ void Gamelog::PrintConsole() */ void Gamelog::PrintDebug(int level) { - this->Print([level](const char *s) { + this->Print([level](const std::string &s) { Debug(gamelog, level, "{}", s); }); } diff --git a/src/gamelog.h b/src/gamelog.h index aa47575972..98ed13d693 100644 --- a/src/gamelog.h +++ b/src/gamelog.h @@ -65,7 +65,7 @@ public: void Reset(); - void Print(std::function proc); + void Print(std::function proc); void PrintDebug(int level); void PrintConsole(); From a312a6c1b2ef62092853c3da7a1895921415e315 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Thu, 27 Apr 2023 22:18:53 +0200 Subject: [PATCH 19/34] Codechange: make md5sumToString std::string compatible --- src/console_cmds.cpp | 4 +--- src/gamelog.cpp | 4 +--- src/network/network_client.cpp | 4 +--- src/network/network_content_gui.cpp | 4 +--- src/newgrf_config.cpp | 8 ++------ src/newgrf_gui.cpp | 10 +++++----- src/openttd.cpp | 5 ++--- src/saveload/afterload.cpp | 12 ++++-------- src/screenshot.cpp | 4 +--- src/settings.cpp | 7 ++----- src/string.cpp | 14 +++----------- src/string_func.h | 2 +- 12 files changed, 24 insertions(+), 54 deletions(-) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index bc3a4434fa..267fa1b5d7 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -1899,9 +1899,7 @@ static void OutputContentState(const ContentInfo *const ci) static const char * const states[] = { "Not selected", "Selected", "Dep Selected", "Installed", "Unknown" }; static const TextColour state_to_colour[] = { CC_COMMAND, CC_INFO, CC_INFO, CC_WHITE, CC_ERROR }; - char buf[sizeof(ci->md5sum) * 2 + 1]; - md5sumToString(buf, lastof(buf), ci->md5sum); - IConsolePrint(state_to_colour[ci->state], "{}, {}, {}, {}, {:08X}, {}", ci->id, types[ci->type - 1], states[ci->state], ci->name, ci->unique_id, buf); + IConsolePrint(state_to_colour[ci->state], "{}, {}, {}, {}, {:08X}, {}", ci->id, types[ci->type - 1], states[ci->state], ci->name, ci->unique_id, MD5SumToString(ci->md5sum)); } DEF_CONSOLE_CMD(ConContent) diff --git a/src/gamelog.cpp b/src/gamelog.cpp index 8477ab90cd..6a4632fcb7 100644 --- a/src/gamelog.cpp +++ b/src/gamelog.cpp @@ -125,9 +125,7 @@ template static void AddGrfInfo(T &outputIterator, uint grfid, const uint8 *md5sum, const GRFConfig *gc) { if (md5sum != nullptr) { - char txt[40]; - md5sumToString(txt, lastof(txt), md5sum); - fmt::format_to(outputIterator, "GRF ID {:08X}, checksum {}", BSWAP32(grfid), txt); + fmt::format_to(outputIterator, "GRF ID {:08X}, checksum {}", BSWAP32(grfid), MD5SumToString(md5sum)); } else { fmt::format_to(outputIterator, "GRF ID {:08X}", BSWAP32(grfid)); } diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 3bfdaa118d..6ffecebe1e 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -666,9 +666,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHECK_NEWGRFS(P const GRFConfig *f = FindGRFConfig(c.grfid, FGCM_EXACT, c.md5sum); if (f == nullptr) { /* We do not know this GRF, bail out of initialization */ - char buf[sizeof(c.md5sum) * 2 + 1]; - md5sumToString(buf, lastof(buf), c.md5sum); - Debug(grf, 0, "NewGRF {:08X} not found; checksum {}", BSWAP32(c.grfid), buf); + Debug(grf, 0, "NewGRF {:08X} not found; checksum {}", BSWAP32(c.grfid), MD5SumToString(c.md5sum)); ret = NETWORK_RECV_STATUS_NEWGRF_MISMATCH; } } diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index dcafc80112..3f8c97e348 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -365,9 +365,7 @@ class NetworkContentListWindow : public Window, ContentCallback { if (!first) url.push_back(','); first = false; - char buf[33]; - md5sumToString(buf, lastof(buf), ci->md5sum); - fmt::format_to(std::back_inserter(url), "{:08X}:{}", ci->unique_id, buf); + fmt::format_to(std::back_inserter(url), "{:08X}:{}", ci->unique_id, MD5SumToString(ci->md5sum)); } } else { url += "do=searchtext&q="; diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index 0391e2c000..d51bb48a5b 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -517,14 +517,11 @@ GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig) for (GRFConfig *c = grfconfig; c != nullptr; c = c->next) { const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum); if (f == nullptr || HasBit(f->flags, GCF_INVALID)) { - char buf[256]; - /* If we have not found the exactly matching GRF try to find one with the * same grfid, as it most likely is compatible */ f = FindGRFConfig(c->ident.grfid, FGCM_COMPATIBLE, nullptr, c->version); if (f != nullptr) { - md5sumToString(buf, lastof(buf), c->ident.md5sum); - Debug(grf, 1, "NewGRF {:08X} ({}) not found; checksum {}. Compatibility mode on", BSWAP32(c->ident.grfid), c->filename, buf); + Debug(grf, 1, "NewGRF {:08X} ({}) not found; checksum {}. Compatibility mode on", BSWAP32(c->ident.grfid), c->filename, MD5SumToString(c->ident.md5sum)); if (!HasBit(c->flags, GCF_COMPATIBLE)) { /* Preserve original_md5sum after it has been assigned */ SetBit(c->flags, GCF_COMPATIBLE); @@ -537,8 +534,7 @@ GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig) } /* No compatible grf was found, mark it as disabled */ - md5sumToString(buf, lastof(buf), c->ident.md5sum); - Debug(grf, 0, "NewGRF {:08X} ({}) not found; checksum {}", BSWAP32(c->ident.grfid), c->filename, buf); + Debug(grf, 0, "NewGRF {:08X} ({}) not found; checksum {}", BSWAP32(c->ident.grfid), c->filename, MD5SumToString(c->ident.md5sum)); c->status = GCS_NOT_FOUND; res = GLC_NOT_FOUND; diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 0181556a86..0cd608de4a 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -92,9 +92,8 @@ static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params) } /* Prepare and draw GRF ID */ - char buff[256]; - seprintf(buff, lastof(buff), "%08X", BSWAP32(c->ident.grfid)); - SetDParamStr(0, buff); + std::string tmp = fmt::format("{:08X}", BSWAP32(c->ident.grfid)); + SetDParamStr(0, tmp); tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_GRF_ID); if ((_settings_client.gui.newgrf_developer_tools || _settings_client.gui.newgrf_show_old_versions) && c->version != 0) { @@ -107,13 +106,14 @@ static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params) } /* Prepare and draw MD5 sum */ - md5sumToString(buff, lastof(buff), c->ident.md5sum); - SetDParamStr(0, buff); + tmp = MD5SumToString(c->ident.md5sum); + SetDParamStr(0, tmp); tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_MD5SUM); /* Show GRF parameter list */ if (show_params) { if (c->num_params > 0) { + char buff[256]; GRFBuildParamList(buff, c, lastof(buff)); SetDParam(0, STR_JUST_RAW_STRING); SetDParamStr(1, buff); diff --git a/src/openttd.cpp b/src/openttd.cpp index 52a466f78d..97face4e6c 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -257,9 +257,8 @@ static void WriteSavegameInfo(const char *name) message += "NewGRFs:\n"; if (_load_check_data.HasNewGrfs()) { for (GRFConfig *c = _load_check_data.grfconfig; c != nullptr; c = c->next) { - char md5sum[33]; - md5sumToString(md5sum, lastof(md5sum), HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum); - fmt::format_to(std::back_inserter(message), "{:08X} {} {}\n", c->ident.grfid, md5sum, c->filename); + fmt::format_to(std::back_inserter(message), "{:08X} {} {}\n", c->ident.grfid, + MD5SumToString(HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum), c->filename); } } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 0b8ae1cff7..822de66802 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -388,16 +388,12 @@ static void CDECL HandleSavegameLoadCrash(int signum) for (const GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (HasBit(c->flags, GCF_COMPATIBLE)) { const GRFIdentifier *replaced = _gamelog.GetOverriddenIdentifier(c); - char original_md5[40]; - char replaced_md5[40]; - md5sumToString(original_md5, lastof(original_md5), c->original_md5sum); - md5sumToString(replaced_md5, lastof(replaced_md5), replaced->md5sum); - fmt::format_to(std::back_inserter(message), "NewGRF {:08X} (checksum {}) not found.\n Loaded NewGRF \"{}\" (checksum {}) with same GRF ID instead.\n", BSWAP32(c->ident.grfid), original_md5, c->filename, replaced_md5); + fmt::format_to(std::back_inserter(message), "NewGRF {:08X} (checksum {}) not found.\n Loaded NewGRF \"{}\" (checksum {}) with same GRF ID instead.\n", + BSWAP32(c->ident.grfid), MD5SumToString(c->original_md5sum), c->filename, MD5SumToString(replaced->md5sum)); } if (c->status == GCS_NOT_FOUND) { - char buf[40]; - md5sumToString(buf, lastof(buf), c->ident.md5sum); - fmt::format_to(std::back_inserter(message), "NewGRF {:08X} ({}) not found; checksum {}.\n", BSWAP32(c->ident.grfid), c->filename, buf); + fmt::format_to(std::back_inserter(message), "NewGRF {:08X} ({}) not found; checksum {}.\n", + BSWAP32(c->ident.grfid), c->filename, MD5SumToString(c->ident.md5sum)); } } } else { diff --git a/src/screenshot.cpp b/src/screenshot.cpp index f0176b31d5..2f3a8257cb 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -320,9 +320,7 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user fmt::format_to(std::back_inserter(message), "Graphics set: {} ({})\n", BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet()->version); message += "NewGRFs:\n"; for (const GRFConfig *c = _game_mode == GM_MENU ? nullptr : _grfconfig; c != nullptr; c = c->next) { - char buf[33]; - md5sumToString(buf, lastof(buf), c->ident.md5sum); - fmt::format_to(std::back_inserter(message), "{:08X} {} {}\n", BSWAP32(c->ident.grfid), buf, c->filename); + fmt::format_to(std::back_inserter(message), "{:08X} {} {}\n", BSWAP32(c->ident.grfid), MD5SumToString(c->ident.md5sum), c->filename); } message += "\nCompanies:\n"; for (const Company *c : Company::Iterate()) { diff --git a/src/settings.cpp b/src/settings.cpp index 6dfd8e240d..d650d5594d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1135,14 +1135,11 @@ static void GRFSaveConfig(IniFile &ini, const char *grpname, const GRFConfig *li const GRFConfig *c; for (c = list; c != nullptr; c = c->next) { - /* Hex grfid (4 bytes in nibbles), "|", hex md5sum (16 bytes in nibbles), "|", file system path. */ - char key[4 * 2 + 1 + 16 * 2 + 1 + MAX_PATH]; char params[512]; GRFBuildParamList(params, c, lastof(params)); - char *pos = key + seprintf(key, lastof(key), "%08X|", BSWAP32(c->ident.grfid)); - pos = md5sumToString(pos, lastof(key), c->ident.md5sum); - seprintf(pos, lastof(key), "|%s", c->filename); + std::string key = fmt::format("{:08X}|{}|{}", BSWAP32(c->ident.grfid), + MD5SumToString(c->ident.md5sum), c->filename); group->GetItem(key, true)->SetValue(params); } } diff --git a/src/string.cpp b/src/string.cpp index 55a7ad4ced..35b3dc5b3d 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -612,20 +612,12 @@ int CDECL seprintf(char *str, const char *last, const char *format, ...) /** * Convert the md5sum to a hexadecimal string representation - * @param buf buffer to put the md5sum into - * @param last last character of buffer (usually lastof(buf)) * @param md5sum the md5sum itself - * @return a pointer to the next character after the md5sum + * @return the string representation of the md5sum. */ -char *md5sumToString(char *buf, const char *last, const uint8 md5sum[16]) +std::string MD5SumToString(const uint8 md5sum[16]) { - char *p = buf; - - for (uint i = 0; i < 16; i++) { - p += seprintf(p, last, "%02X", md5sum[i]); - } - - return p; + return FormatArrayAsHex({md5sum, 16}); } diff --git a/src/string_func.h b/src/string_func.h index 1abbd470f1..c03101c213 100644 --- a/src/string_func.h +++ b/src/string_func.h @@ -86,7 +86,7 @@ static inline size_t ttd_strnlen(const char *str, size_t maxlen) return t - str; } -char *md5sumToString(char *buf, const char *last, const uint8 md5sum[16]); +std::string MD5SumToString(const uint8 md5sum[16]); bool IsValidChar(WChar key, CharSetFilter afilter); From f78aa1e72061009752a0dabf0a5a46749a3e7a80 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Thu, 27 Apr 2023 20:28:09 +0200 Subject: [PATCH 20/34] Codechange: use std::unique_ptr to manager GRFErrors in GRFConfig --- src/newgrf.cpp | 20 +++++++------------- src/newgrf_config.cpp | 3 +-- src/newgrf_config.h | 2 +- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 4336e7b76f..3921208ef0 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -449,12 +449,11 @@ static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = nul if (config == _cur.grfconfig) _cur.skip_sprites = -1; if (message != STR_NULL) { - delete config->error; - config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message); + config->error = std::make_unique(STR_NEWGRF_ERROR_MSG_FATAL, message); if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line; } - return config->error; + return config->error.get(); } /** @@ -7134,8 +7133,7 @@ static void GRFLoadError(ByteReader *buf) DisableGrf(); /* Make sure we show fatal errors, instead of silly infos from before */ - delete _cur.grfconfig->error; - _cur.grfconfig->error = nullptr; + _cur.grfconfig->error.reset(); } if (message_id >= lengthof(msgstr) && message_id != 0xFF) { @@ -7151,7 +7149,8 @@ static void GRFLoadError(ByteReader *buf) /* For now we can only show one message per newgrf file. */ if (_cur.grfconfig->error != nullptr) return; - GRFError *error = new GRFError(sevstr[severity]); + _cur.grfconfig->error = std::make_unique(sevstr[severity]); + GRFError *error = _cur.grfconfig->error.get(); if (message_id == 0xFF) { /* This is a custom error message. */ @@ -7181,8 +7180,6 @@ static void GRFLoadError(ByteReader *buf) uint param_number = buf->ReadByte(); error->param_value[i] = _cur.grffile->GetParam(param_number); } - - _cur.grfconfig->error = error; } /* Action 0x0C */ @@ -8723,10 +8720,7 @@ static void ResetNewGRF() static void ResetNewGRFErrors() { for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { - if (!HasBit(c->flags, GCF_COPY) && c->error != nullptr) { - delete c->error; - c->error = nullptr; - } + c->error.reset(); } } @@ -10011,7 +10005,7 @@ void LoadNewGRF(uint load_index, uint num_baseset) if (num_non_static == NETWORK_MAX_GRF_COUNT) { Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename); c->status = GCS_DISABLED; - c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED); + c->error = std::make_unique(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED); continue; } num_non_static++; diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index d51bb48a5b..bb4ed080f2 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -64,7 +64,7 @@ GRFConfig::GRFConfig(const GRFConfig &config) : MemCpyT(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum)); MemCpyT(this->param, config.param, lengthof(this->param)); if (config.filename != nullptr) this->filename = stredup(config.filename); - if (config.error != nullptr) this->error = new GRFError(*config.error); + if (config.error != nullptr) this->error = std::make_unique(*config.error); for (uint i = 0; i < config.param_info.size(); i++) { if (config.param_info[i] == nullptr) { this->param_info.push_back(nullptr); @@ -80,7 +80,6 @@ GRFConfig::~GRFConfig() /* GCF_COPY as in NOT stredupped/alloced the filename */ if (!HasBit(this->flags, GCF_COPY)) { free(this->filename); - delete this->error; } for (uint i = 0; i < this->param_info.size(); i++) delete this->param_info[i]; diff --git a/src/newgrf_config.h b/src/newgrf_config.h index 6f4b5c0028..5a089b7093 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -166,7 +166,7 @@ struct GRFConfig : ZeroedMemoryAllocator { GRFTextWrapper name; ///< NOSAVE: GRF name (Action 0x08) GRFTextWrapper info; ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08) GRFTextWrapper url; ///< NOSAVE: URL belonging to this GRF. - GRFError *error; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B) + std::unique_ptr error; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B) uint32 version; ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown uint32 min_loadable_version; ///< NOSAVE: Minimum compatible version a NewGRF can define From 3901ef9760495355433e6e7d6c39655ae256c5bd Mon Sep 17 00:00:00 2001 From: Rubidium Date: Thu, 27 Apr 2023 20:42:25 +0200 Subject: [PATCH 21/34] Codechange: use std::string for the GRF filenames --- src/network/core/tcp_content.cpp | 2 +- src/newgrf.cpp | 21 ++++++++++----------- src/newgrf.h | 2 +- src/newgrf_config.cpp | 24 ++++++++---------------- src/newgrf_config.h | 4 ++-- src/newgrf_gui.cpp | 4 ++-- 6 files changed, 24 insertions(+), 33 deletions(-) diff --git a/src/network/core/tcp_content.cpp b/src/network/core/tcp_content.cpp index 14108fb8ab..dbbb70dcaa 100644 --- a/src/network/core/tcp_content.cpp +++ b/src/network/core/tcp_content.cpp @@ -71,7 +71,7 @@ const char *ContentInfo::GetTextfile(TextfileType type) const break; case CONTENT_TYPE_NEWGRF: { const GRFConfig *gc = FindGRFConfig(BSWAP32(this->unique_id), FGCM_EXACT, this->md5sum); - tmp = gc != nullptr ? gc->filename : nullptr; + tmp = gc != nullptr ? gc->filename.c_str() : nullptr; break; } case CONTENT_TYPE_BASE_GRAPHICS: diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 3921208ef0..4d343468d9 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -414,10 +414,10 @@ static GRFFile *GetFileByGRFID(uint32 grfid) * @param filename The filename to obtain the file for. * @return The file. */ -static GRFFile *GetFileByFilename(const char *filename) +static GRFFile *GetFileByFilename(const std::string &filename) { for (GRFFile * const file : _grf_files) { - if (strcmp(file->filename, filename) == 0) return file; + if (file->filename == filename) return file; } return nullptr; } @@ -8882,7 +8882,7 @@ static void InitNewGRFFile(const GRFConfig *config) */ GRFFile::GRFFile(const GRFConfig *config) { - this->filename = stredup(config->filename); + this->filename = config->filename; this->grfid = config->ident.grfid; /* Initialise local settings to defaults */ @@ -8922,7 +8922,6 @@ GRFFile::GRFFile(const GRFConfig *config) GRFFile::~GRFFile() { - free(this->filename); delete[] this->language_map; } @@ -9186,7 +9185,7 @@ static void FinaliseCargoArray() * @param filename The filename of the newgrf this house was defined in. * @return Whether the given housespec is valid. */ -static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename) +static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const std::string &filename) { if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && (next1 == nullptr || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) || @@ -9194,7 +9193,7 @@ static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseS (next2 == nullptr || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 || next3 == nullptr || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) { hs->enabled = false; - if (filename != nullptr) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id); + if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id); return false; } @@ -9204,13 +9203,13 @@ static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseS if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) || ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) { hs->enabled = false; - if (filename != nullptr) Debug(grf, 1, "FinaliseHouseArray: {} defines multitile house {} with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id); + if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines multitile house {} with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id); return false; } /* Substitute type is also used for override, and having an override with a different size causes crashes. * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/ - if (filename != nullptr && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) { + if (!filename.empty() && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) { hs->enabled = false; Debug(grf, 1, "FinaliseHouseArray: {} defines house {} with different house size then it's substitute type. Disabling house.", filename, hs->grf_prop.local_id); return false; @@ -9219,7 +9218,7 @@ static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseS /* Make sure that additional parts of multitile houses are not available. */ if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) { hs->enabled = false; - if (filename != nullptr) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id); + if (!filename.empty()) Debug(grf, 1, "FinaliseHouseArray: {} defines house {} without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id); return false; } @@ -9297,7 +9296,7 @@ static void FinaliseHouseArray() /* We need to check all houses again to we are sure that multitile houses * did get consecutive IDs and none of the parts are missing. */ - if (!IsHouseSpecValid(hs, next1, next2, next3, nullptr)) { + if (!IsHouseSpecValid(hs, next1, next2, next3, std::string{})) { /* GetHouseNorthPart checks 3 houses that are directly before * it in the house pool. If any of those houses have multi-tile * flags set it assumes it's part of a multitile house. Since @@ -9606,7 +9605,7 @@ static void LoadNewGRFFileFromFile(GRFConfig *config, GrfLoadingStage stage, Spr */ void LoadNewGRFFile(GRFConfig *config, GrfLoadingStage stage, Subdirectory subdir, bool temporary) { - const char *filename = config->filename; + const std::string &filename = config->filename; /* A .grf file is activated only if it was active when the game was * started. If a game is loaded, only its active .grfs will be diff --git a/src/newgrf.h b/src/newgrf.h index 4110cb1243..af7af801d0 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -105,7 +105,7 @@ struct GRFLabel { /** Dynamic data of a loaded NewGRF */ struct GRFFile : ZeroedMemoryAllocator { - char *filename; + std::string filename; uint32 grfid; byte grf_version; diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index bb4ed080f2..77f82fcb2b 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -32,13 +32,11 @@ /** * Create a new GRFConfig. - * @param filename Set the filename of this GRFConfig to filename. The argument - * is copied so the original string isn't needed after the constructor. + * @param filename Set the filename of this GRFConfig to filename. */ -GRFConfig::GRFConfig(const char *filename) : - num_valid_params(lengthof(param)) +GRFConfig::GRFConfig(const std::string &filename) : + filename(filename), num_valid_params(lengthof(param)) { - if (filename != nullptr) this->filename = stredup(filename); } /** @@ -48,6 +46,7 @@ GRFConfig::GRFConfig(const char *filename) : GRFConfig::GRFConfig(const GRFConfig &config) : ZeroedMemoryAllocator(), ident(config.ident), + filename(config.filename), name(config.name), info(config.info), url(config.url), @@ -63,7 +62,6 @@ GRFConfig::GRFConfig(const GRFConfig &config) : { MemCpyT(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum)); MemCpyT(this->param, config.param, lengthof(this->param)); - if (config.filename != nullptr) this->filename = stredup(config.filename); if (config.error != nullptr) this->error = std::make_unique(*config.error); for (uint i = 0; i < config.param_info.size(); i++) { if (config.param_info[i] == nullptr) { @@ -77,11 +75,6 @@ GRFConfig::GRFConfig(const GRFConfig &config) : /** Cleanup a GRFConfig object. */ GRFConfig::~GRFConfig() { - /* GCF_COPY as in NOT stredupped/alloced the filename */ - if (!HasBit(this->flags, GCF_COPY)) { - free(this->filename); - } - for (uint i = 0; i < this->param_info.size(); i++) delete this->param_info[i]; } @@ -104,7 +97,7 @@ void GRFConfig::CopyParams(const GRFConfig &src) const char *GRFConfig::GetName() const { const char *name = GetGRFStringFromGRFText(this->name); - return StrEmpty(name) ? this->filename : name; + return StrEmpty(name) ? this->filename.c_str() : name; } /** @@ -546,8 +539,7 @@ compatible_grf: * When the GCF_COPY flag is set, it is certain that the filename is * already a local one, so there is no need to replace it. */ if (!HasBit(c->flags, GCF_COPY)) { - free(c->filename); - c->filename = stredup(f->filename); + c->filename = f->filename; memcpy(c->ident.md5sum, f->ident.md5sum, sizeof(c->ident.md5sum)); c->name = f->name; c->info = f->name; @@ -644,7 +636,7 @@ bool GRFFileScanner::AddFile(const std::string &filename, size_t basepath_length const char *name = nullptr; if (c->name != nullptr) name = GetGRFStringFromGRFText(c->name); - if (name == nullptr) name = c->filename; + if (name == nullptr) name = c->filename.c_str(); UpdateNewGRFScanStatus(this->num_scanned, name); VideoDriver::GetInstance()->GameLoopPause(); @@ -797,5 +789,5 @@ char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last) */ const char *GRFConfig::GetTextfile(TextfileType type) const { - return ::GetTextfile(type, NEWGRF_DIR, this->filename); + return ::GetTextfile(type, NEWGRF_DIR, this->filename.c_str()); } diff --git a/src/newgrf_config.h b/src/newgrf_config.h index 5a089b7093..3e5a56739a 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -153,7 +153,7 @@ struct GRFParameterInfo { /** Information about GRF, used in the game and (part of it) in savegames */ struct GRFConfig : ZeroedMemoryAllocator { - GRFConfig(const char *filename = nullptr); + GRFConfig(const std::string &filename = std::string{}); GRFConfig(const GRFConfig &config); ~GRFConfig(); @@ -162,7 +162,7 @@ struct GRFConfig : ZeroedMemoryAllocator { GRFIdentifier ident; ///< grfid and md5sum to uniquely identify newgrfs uint8 original_md5sum[16]; ///< MD5 checksum of original file if only a 'compatible' file was loaded - char *filename; ///< Filename - either with or without full path + std::string filename; ///< Filename - either with or without full path GRFTextWrapper name; ///< NOSAVE: GRF name (Action 0x08) GRFTextWrapper info; ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08) GRFTextWrapper url; ///< NOSAVE: URL belonging to this GRF. diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 0cd608de4a..63a326a975 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -86,7 +86,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params) } /* Draw filename or not if it is not known (GRF sent over internet) */ - if (c->filename != nullptr) { + if (!c->filename.empty()) { SetDParamStr(0, c->filename); tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_FILENAME); } @@ -1442,7 +1442,7 @@ private: { filter.ResetState(); filter.AddLine((*a)->GetName()); - filter.AddLine((*a)->filename); + filter.AddLine((*a)->filename.c_str()); filter.AddLine((*a)->GetDescription()); return filter.GetState();; } From 5e185d5328379a6efe02dcb8dfe0ffe2a795b67c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 25 Apr 2023 17:52:08 +0100 Subject: [PATCH 22/34] Codechange: Draw tooltip text in black. --- src/misc_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 5d272080b8..ad2e9d7b4e 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -727,7 +727,7 @@ struct TooltipsWindow : public Window for (uint arg = 0; arg < this->paramcount; arg++) { SetDParam(arg, this->params[arg]); } - DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect).Shrink(WidgetDimensions::scaled.fullbevel), this->string_id, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect).Shrink(WidgetDimensions::scaled.fullbevel), this->string_id, TC_BLACK, SA_CENTER); } void OnMouseLoop() override From e18f688db5268cf2aac8e7266c756bb3f4c0d1ce Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 25 Apr 2023 09:45:05 +0100 Subject: [PATCH 23/34] Codechange: Remove various COMMA strings. --- src/build_vehicle_gui.cpp | 4 ++-- src/company_gui.cpp | 4 ++-- src/depot_gui.cpp | 4 ++-- src/graph_gui.cpp | 4 ++-- src/group_gui.cpp | 2 +- src/lang/english.txt | 6 ------ src/newgrf_debug_gui.cpp | 4 ++-- src/order_gui.cpp | 4 ++-- src/vehicle_gui.cpp | 10 +++++----- 9 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 8d632a66c6..b9d8962564 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1028,7 +1028,7 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li if (show_count) { replace_icon = GetSpriteSize(SPR_GROUP_REPLACE_ACTIVE); SetDParamMaxDigits(0, 3, FS_SMALL); - count_width = GetStringBoundingBox(STR_TINY_BLACK_COMMA).width; + count_width = GetStringBoundingBox(STR_JUST_COMMA, FS_SMALL).width; } Rect tr = ir.Indent(circle_width + WidgetDimensions::scaled.hsep_normal + sprite_width + WidgetDimensions::scaled.hsep_wide, rtl); // Name position @@ -1067,7 +1067,7 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li DrawVehicleEngine(r.left, r.right, sprite_x, y + sprite_y_offset, item.engine_id, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(item.engine_id, _local_company), EIT_PURCHASE); if (show_count) { SetDParam(0, num_engines); - DrawString(cr.left, cr.right, y + small_text_y_offset, STR_TINY_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); + DrawString(cr.left, cr.right, y + small_text_y_offset, STR_JUST_COMMA, TC_BLACK, SA_RIGHT | SA_FORCE, false, FS_SMALL); if (EngineHasReplacementForCompany(Company::Get(_local_company), item.engine_id, selected_group)) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, num_engines == 0 ? PALETTE_CRASH : PAL_NONE, rr.left, y + replace_icon_y_offset); } if (has_variants) { diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 986e0b60a1..99f3603014 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -2000,7 +2000,7 @@ struct CompanyInfrastructureWindow : Window max_cost = std::max(max_cost, AirportMaintenanceCost(c->index)); SetDParamMaxValue(0, max_val); - uint count_width = GetStringBoundingBox(STR_WHITE_COMMA).width + WidgetDimensions::scaled.hsep_indent; // Reserve some wiggle room + uint count_width = GetStringBoundingBox(STR_JUST_COMMA).width + WidgetDimensions::scaled.hsep_indent; // Reserve some wiggle room if (_settings_game.economy.infrastructure_maintenance) { SetDParamMaxValue(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year @@ -2032,7 +2032,7 @@ struct CompanyInfrastructureWindow : Window void DrawCountLine(const Rect &r, int &y, int count, Money monthly_cost) const { SetDParam(0, count); - DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_COMMA, TC_FROMSTRING, SA_RIGHT); + DrawString(r.left, r.right, y += FONT_HEIGHT_NORMAL, STR_JUST_COMMA, TC_WHITE, SA_RIGHT); if (_settings_game.economy.infrastructure_maintenance) { SetDParam(0, monthly_cost * 12); // Convert to per year diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 7f454946ce..33f4675290 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -360,7 +360,7 @@ struct DepotWindow : Window { DrawSpriteIgnorePadding((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, false, SA_CENTER); SetDParam(0, v->unitnumber); - DrawString(text, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA); + DrawString(text, STR_JUST_COMMA, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? TC_BLACK : TC_RED); } } @@ -669,7 +669,7 @@ struct DepotWindow : Window { } SetDParamMaxDigits(0, this->unitnumber_digits); - Dimension unumber = GetStringBoundingBox(STR_BLACK_COMMA); + Dimension unumber = GetStringBoundingBox(STR_JUST_COMMA); if (this->type == VEH_TRAIN || this->type == VEH_ROAD) { min_height = std::max(unumber.height, this->flag_size.height); diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 5510aa7439..47e596177a 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -1159,7 +1159,7 @@ struct PerformanceRatingDetailWindow : Window { score_info_width = std::max(score_info_width, GetStringBoundingBox(STR_PERFORMANCE_DETAIL_VEHICLES + i).width); } SetDParamMaxValue(0, 1000); - score_info_width += GetStringBoundingBox(STR_BLACK_COMMA).width + WidgetDimensions::scaled.hsep_wide; + score_info_width += GetStringBoundingBox(STR_JUST_COMMA).width + WidgetDimensions::scaled.hsep_wide; SetDParamMaxValue(0, 100); this->bar_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_PERCENT).width + WidgetDimensions::scaled.hsep_indent * 2; // Wide bars! @@ -1245,7 +1245,7 @@ struct PerformanceRatingDetailWindow : Window { /* Draw the score */ SetDParam(0, score); - DrawString(this->score_info_left, this->score_info_right, text_top, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT); + DrawString(this->score_info_left, this->score_info_right, text_top, STR_JUST_COMMA, TC_BLACK, SA_RIGHT); /* Calculate the %-bar */ uint x = Clamp(val, 0, needed) * this->bar_width / needed; diff --git a/src/group_gui.cpp b/src/group_gui.cpp index a671406ed6..ec6c60de9d 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -321,7 +321,7 @@ private: int num_vehicle = GroupStatistics::Get(this->vli.company, g_id, this->vli.vtype).num_vehicle; if (IsAllGroupID(g_id) || IsDefaultGroupID(g_id) || num_vehicle_with_subgroups == num_vehicle) { SetDParam(0, num_vehicle); - DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, STR_TINY_COMMA, colour, SA_RIGHT | SA_FORCE); + DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, STR_JUST_COMMA, colour, SA_RIGHT | SA_FORCE, false, FS_SMALL); } else { SetDParam(0, num_vehicle); SetDParam(1, num_vehicle_with_subgroups - num_vehicle); diff --git a/src/lang/english.txt b/src/lang/english.txt index 8f813a4b0c..f9286058f7 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5606,12 +5606,6 @@ STR_JUST_RAW_STRING :{RAW_STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{RAW_STRING} # Slightly 'raw' stringcodes with colour or size -STR_BLACK_COMMA :{BLACK}{COMMA} -STR_TINY_BLACK_COMMA :{TINY_FONT}{BLACK}{COMMA} -STR_TINY_COMMA :{TINY_FONT}{COMMA} -STR_BLUE_COMMA :{BLUE}{COMMA} -STR_RED_COMMA :{RED}{COMMA} -STR_WHITE_COMMA :{WHITE}{COMMA} STR_TINY_BLACK_DECIMAL :{TINY_FONT}{BLACK}{DECIMAL} STR_COMPANY_MONEY :{WHITE}{CURRENCY_LONG} STR_BLACK_DATE_LONG :{BLACK}{DATE_LONG} diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 2ee3bcf79c..ff927c2952 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -879,7 +879,7 @@ struct SpriteAlignerWindow : Window { break; case WID_SA_LIST: SetDParamMaxDigits(0, 6); - size->width = GetStringBoundingBox(STR_BLACK_COMMA).width + padding.width; + size->width = GetStringBoundingBox(STR_JUST_COMMA).width + padding.width; resize->height = FONT_HEIGHT_NORMAL + padding.height; resize->width = 1; fill->height = resize->height; @@ -928,7 +928,7 @@ struct SpriteAlignerWindow : Window { Rect ir = r.Shrink(WidgetDimensions::scaled.matrix); for (int i = this->vscroll->GetPosition(); i < max; i++) { SetDParam(0, list[i]); - DrawString(ir, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); + DrawString(ir, STR_JUST_COMMA, TC_BLACK, SA_RIGHT | SA_FORCE); ir.top += step_size; } break; diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 2f68e0b839..4e74ea9694 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1617,7 +1617,7 @@ static const NWidgetPart _nested_orders_train_widgets[] = { NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_COMPARATOR), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP), SetResize(1, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_COND_VALUE), SetMinimalSize(124, 12), SetFill(1, 0), - SetDataTip(STR_BLACK_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0), + SetDataTip(STR_JUST_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0), EndContainer(), EndContainer(), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_O_SHARED_ORDER_LIST), SetMinimalSize(12, 12), SetDataTip(SPR_SHARED_ORDERS_ICON, STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP), @@ -1691,7 +1691,7 @@ static const NWidgetPart _nested_orders_widgets[] = { NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_COMPARATOR), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP), SetResize(1, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_COND_VALUE), SetMinimalSize(124, 12), SetFill(1, 0), - SetDataTip(STR_BLACK_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0), + SetDataTip(STR_JUST_COMMA, STR_ORDER_CONDITIONAL_VALUE_TOOLTIP), SetResize(1, 0), EndContainer(), EndContainer(), diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index ec66954299..bbde5852db 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1721,15 +1721,15 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int if (show_orderlist) DrawSmallOrderList(v, olr.left, olr.right, ir.top, this->order_arrow_width, v->cur_real_order_index); - StringID str; + TextColour tc; if (v->IsChainInDepot()) { - str = STR_BLUE_COMMA; + tc = TC_BLUE; } else { - str = (v->age > v->max_age - DAYS_IN_LEAP_YEAR) ? STR_RED_COMMA : STR_BLACK_COMMA; + tc = (v->age > v->max_age - DAYS_IN_LEAP_YEAR) ? TC_RED : TC_BLACK; } SetDParam(0, v->unitnumber); - DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, str); + DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, STR_JUST_COMMA, tc); break; } @@ -1744,7 +1744,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int if (show_orderlist) DrawSmallOrderList((vehgroup.vehicles_begin[0])->GetFirstOrder(), olr.left, olr.right, ir.top, this->order_arrow_width); SetDParam(0, vehgroup.NumVehicles()); - DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, STR_BLACK_COMMA); + DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, STR_JUST_COMMA, TC_BLACK); break; default: From f1d0a263240d11bb62e7cfc5a34c251d65210dd5 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 25 Apr 2023 09:49:44 +0100 Subject: [PATCH 24/34] Codechange: Remove STR_TINY_BLACK_DECIMAL. --- src/depot_gui.cpp | 4 ++-- src/lang/english.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 33f4675290..fa8aca26ec 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -331,7 +331,7 @@ struct DepotWindow : Window { SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE)); SetDParam(1, 1); Rect count = text.WithWidth(this->count_width - WidgetDimensions::scaled.hsep_normal, !rtl); - DrawString(count.left, count.right, count.bottom - FONT_HEIGHT_SMALL + 1, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter + DrawString(count.left, count.right, count.bottom - FONT_HEIGHT_SMALL + 1, STR_JUST_DECIMAL, TC_BLACK, SA_RIGHT, false, FS_SMALL); // Draw the counter break; } @@ -663,7 +663,7 @@ struct DepotWindow : Window { if (this->type == VEH_TRAIN) { SetDParamMaxValue(0, 1000, 0, FS_SMALL); SetDParam(1, 1); - this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WidgetDimensions::scaled.hsep_normal; + this->count_width = GetStringBoundingBox(STR_JUST_DECIMAL, FS_SMALL).width + WidgetDimensions::scaled.hsep_normal; } else { this->count_width = 0; } diff --git a/src/lang/english.txt b/src/lang/english.txt index f9286058f7..3e6b4aac3f 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5595,6 +5595,7 @@ STR_JUST_COMMA :{COMMA} STR_JUST_CURRENCY_SHORT :{CURRENCY_SHORT} STR_JUST_CURRENCY_LONG :{CURRENCY_LONG} STR_JUST_CARGO_LIST :{CARGO_LIST} +STR_JUST_DECIMAL :{DECIMAL} STR_JUST_INT :{NUM} STR_JUST_DATE_TINY :{DATE_TINY} STR_JUST_DATE_SHORT :{DATE_SHORT} @@ -5606,7 +5607,6 @@ STR_JUST_RAW_STRING :{RAW_STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{RAW_STRING} # Slightly 'raw' stringcodes with colour or size -STR_TINY_BLACK_DECIMAL :{TINY_FONT}{BLACK}{DECIMAL} STR_COMPANY_MONEY :{WHITE}{CURRENCY_LONG} STR_BLACK_DATE_LONG :{BLACK}{DATE_LONG} STR_WHITE_DATE_LONG :{WHITE}{DATE_LONG} From a2d76421953885e49b29b5be63e530a6885be007 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 25 Apr 2023 09:51:19 +0100 Subject: [PATCH 25/34] Codechange: Remove STR_COMPANY_MONEY. --- src/lang/english.txt | 1 - src/statusbar_gui.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 3e6b4aac3f..d846381bed 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5607,7 +5607,6 @@ STR_JUST_RAW_STRING :{RAW_STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{RAW_STRING} # Slightly 'raw' stringcodes with colour or size -STR_COMPANY_MONEY :{WHITE}{CURRENCY_LONG} STR_BLACK_DATE_LONG :{BLACK}{DATE_LONG} STR_WHITE_DATE_LONG :{WHITE}{DATE_LONG} STR_SHORT_DATE :{WHITE}{DATE_TINY} diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index ffd788065a..b7d906c3fa 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -118,7 +118,7 @@ struct StatusBarWindow : Window { int64 max_money = UINT32_MAX; for (const Company *c : Company::Iterate()) max_money = std::max(c->money, max_money); SetDParam(0, 100LL * max_money); - d = GetStringBoundingBox(STR_COMPANY_MONEY); + d = GetStringBoundingBox(STR_JUST_CURRENCY_LONG); break; } @@ -150,7 +150,7 @@ struct StatusBarWindow : Window { const Company *c = Company::GetIfValid(_local_company); if (c != nullptr) { SetDParam(0, c->money); - DrawString(tr, STR_COMPANY_MONEY, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_JUST_CURRENCY_LONG, TC_WHITE, SA_HOR_CENTER); } } break; From d5fb9e7dc6a9a990e5174a1ab746a09f7e69fd9a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 25 Apr 2023 09:57:55 +0100 Subject: [PATCH 26/34] Codechange: Remove various DATE_LONG strings. --- src/genworld_gui.cpp | 10 +++++----- src/lang/english.txt | 3 --- src/news_gui.cpp | 4 ++-- src/statusbar_gui.cpp | 4 ++-- src/toolbar_gui.cpp | 4 ++-- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index b7fd49b48e..46a10f10f9 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -157,7 +157,7 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { /* Starting date. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), SetFill(0, 1), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_JUST_DATE_LONG, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1), EndContainer(), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0), @@ -301,7 +301,7 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = { /* Starting date. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), SetFill(0, 1), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_JUST_DATE_LONG, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1), EndContainer(), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0), @@ -601,7 +601,7 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_START_DATE_TEXT: SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 0, 1)); - d = GetStringBoundingBox(STR_BLACK_DATE_LONG); + d = GetStringBoundingBox(STR_JUST_DATE_LONG); break; case WID_GL_MAPSIZE_X_PULLDOWN: @@ -1145,7 +1145,7 @@ struct CreateScenarioWindow : public Window switch (widget) { case WID_CS_START_DATE_TEXT: SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 0, 1)); - str = STR_BLACK_DATE_LONG; + str = STR_JUST_DATE_LONG; break; case WID_CS_MAPSIZE_X_PULLDOWN: @@ -1308,7 +1308,7 @@ static const NWidgetPart _nested_create_scenario_widgets[] = { NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetPadding(1, 0, 0, 0), NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_START_DATE_DOWN), SetFill(0, 1), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_START_DATE_TEXT), SetDataTip(STR_JUST_DATE_LONG, STR_NULL), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_START_DATE_UP), SetFill(0, 1), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), EndContainer(), /* Flat map height. */ diff --git a/src/lang/english.txt b/src/lang/english.txt index d846381bed..15aa04ef67 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5607,10 +5607,7 @@ STR_JUST_RAW_STRING :{RAW_STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{RAW_STRING} # Slightly 'raw' stringcodes with colour or size -STR_BLACK_DATE_LONG :{BLACK}{DATE_LONG} -STR_WHITE_DATE_LONG :{WHITE}{DATE_LONG} STR_SHORT_DATE :{WHITE}{DATE_TINY} -STR_DATE_LONG_SMALL :{TINY_FONT}{BLACK}{DATE_LONG} STR_TINY_GROUP :{TINY_FONT}{GROUP} STR_BLACK_INT :{BLACK}{NUM} STR_ORANGE_INT :{ORANGE}{NUM} diff --git a/src/news_gui.cpp b/src/news_gui.cpp index c48f6794bd..bfd8e67914 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -88,7 +88,7 @@ static const NWidgetPart _nested_normal_news_widgets[] = { NWidget(WWT_CLOSEBOX, COLOUR_WHITE, WID_N_CLOSEBOX), SetPadding(0, 0, 0, 1), NWidget(NWID_SPACER), SetFill(1, 0), NWidget(NWID_VERTICAL), - NWidget(WWT_LABEL, COLOUR_WHITE, WID_N_DATE), SetDataTip(STR_DATE_LONG_SMALL, STR_NULL), + NWidget(WWT_LABEL, COLOUR_WHITE, WID_N_DATE), SetDataTip(STR_JUST_DATE_LONG, STR_NULL), SetTextStyle(TC_BLACK, FS_SMALL), NWidget(NWID_SPACER), SetFill(0, 1), EndContainer(), EndContainer(), @@ -165,7 +165,7 @@ static const NWidgetPart _nested_thin_news_widgets[] = { NWidget(WWT_CLOSEBOX, COLOUR_WHITE, WID_N_CLOSEBOX), SetPadding(0, 0, 0, 1), NWidget(NWID_SPACER), SetFill(1, 0), NWidget(NWID_VERTICAL), - NWidget(WWT_LABEL, COLOUR_WHITE, WID_N_DATE), SetDataTip(STR_DATE_LONG_SMALL, STR_NULL), + NWidget(WWT_LABEL, COLOUR_WHITE, WID_N_DATE), SetDataTip(STR_JUST_DATE_LONG, STR_NULL), SetTextStyle(TC_BLACK, FS_SMALL), NWidget(NWID_SPACER), SetFill(0, 1), EndContainer(), EndContainer(), diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index b7d906c3fa..303fb0050c 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -111,7 +111,7 @@ struct StatusBarWindow : Window { switch (widget) { case WID_S_LEFT: SetDParamMaxValue(0, MAX_YEAR * DAYS_IN_YEAR); - d = GetStringBoundingBox(STR_WHITE_DATE_LONG); + d = GetStringBoundingBox(STR_JUST_DATE_LONG); break; case WID_S_RIGHT: { @@ -139,7 +139,7 @@ struct StatusBarWindow : Window { case WID_S_LEFT: /* Draw the date */ SetDParam(0, TimerGameCalendar::date); - DrawString(tr, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_JUST_DATE_LONG, TC_WHITE, SA_HOR_CENTER); break; case WID_S_RIGHT: { diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index cc07a69748..7079266f46 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -2406,7 +2406,7 @@ struct ScenarioEditorToolbarWindow : Window { case WID_TE_DATE: SetDParam(0, TimerGameCalendar::ConvertYMDToDate(MAX_YEAR, 0, 1)); - *size = GetStringBoundingBox(STR_WHITE_DATE_LONG); + *size = GetStringBoundingBox(STR_JUST_DATE_LONG); break; } } @@ -2568,7 +2568,7 @@ static const NWidgetPart _nested_toolb_scen_inner_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_DATE_PANEL), NWidget(NWID_HORIZONTAL), SetPIP(2, 2, 2), SetPadding(1), NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_BACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), SetFill(0, 1), - NWidget(WWT_TEXT, COLOUR_GREY, WID_TE_DATE), SetDataTip(STR_WHITE_DATE_LONG, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE), SetAlignment(SA_CENTER), SetFill(0, 1), + NWidget(WWT_TEXT, COLOUR_GREY, WID_TE_DATE), SetDataTip(STR_JUST_DATE_LONG, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE), SetTextStyle(TC_WHITE), SetAlignment(SA_CENTER), SetFill(0, 1), NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_FORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1), EndContainer(), EndContainer(), From 4767641c8c2f156d9db9b670361c35a8543642b7 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 25 Apr 2023 09:59:52 +0100 Subject: [PATCH 27/34] Codechange: Remove various INT strings. --- src/genworld_gui.cpp | 4 ++-- src/lang/english.txt | 2 -- src/rail_gui.cpp | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 46a10f10f9..8db9771e04 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -260,7 +260,7 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = { /* Heightmap highest peak. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN), SetFill(0, 1), - NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_TEXT), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_HEIGHTMAP_HEIGHT_UP), SetFill(0, 1), EndContainer(), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), @@ -1317,7 +1317,7 @@ static const NWidgetPart _nested_create_scenario_widgets[] = { SetDataTip(STR_SE_MAPGEN_FLAT_WORLD_HEIGHT, STR_NULL), SetPadding(1, 0, 0, 0), NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_DOWN), SetFill(0, 1), SetDataTip(SPR_ARROW_DOWN, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_DOWN), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_TEXT), SetDataTip(STR_JUST_INT, STR_NULL), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_UP), SetFill(0, 1), SetDataTip(SPR_ARROW_UP, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_UP), EndContainer(), EndContainer(), diff --git a/src/lang/english.txt b/src/lang/english.txt index 15aa04ef67..c205d6fa08 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5609,8 +5609,6 @@ STR_JUST_BIG_RAW_STRING :{BIG_FONT}{RAW_ # Slightly 'raw' stringcodes with colour or size STR_SHORT_DATE :{WHITE}{DATE_TINY} STR_TINY_GROUP :{TINY_FONT}{GROUP} -STR_BLACK_INT :{BLACK}{NUM} -STR_ORANGE_INT :{ORANGE}{NUM} STR_WHITE_SIGN :{WHITE}{SIGN} STR_TINY_BLACK_STATION :{TINY_FONT}{BLACK}{STATION} STR_BLACK_STRING :{BLACK}{STRING} diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 24a4a89249..d72675e054 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1886,7 +1886,7 @@ static const NWidgetPart _nested_signal_builder_widgets[] = { NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_PBS), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP), EndContainer(), SetFill(1, 1), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BS_ELECTRIC_PBS_OWAY), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP), EndContainer(), SetFill(1, 1), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetDataTip(STR_NULL, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BS_DRAG_SIGNALS_DENSITY_LABEL), SetDataTip(STR_ORANGE_INT, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetFill(1, 1), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BS_DRAG_SIGNALS_DENSITY_LABEL), SetDataTip(STR_JUST_INT, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP), SetTextStyle(TC_ORANGE), SetFill(1, 1), NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), NWidget(NWID_SPACER), SetFill(1, 0), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_BS_DRAG_SIGNALS_DENSITY_DECREASE), SetMinimalSize(9, 12), SetDataTip(AWV_DECREASE, STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP), From 0880616851e2107d4e183b5679c90d2257b5da35 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 25 Apr 2023 10:03:48 +0100 Subject: [PATCH 28/34] Codechange: Remove various STRING strings. --- src/airport_gui.cpp | 14 ++++------ src/autoreplace_gui.cpp | 2 +- src/build_vehicle_gui.cpp | 2 +- src/company_gui.cpp | 40 +++++++++++++-------------- src/framerate_gui.cpp | 2 +- src/genworld_gui.cpp | 4 +-- src/goal_gui.cpp | 48 ++++++++++++++++----------------- src/group_gui.cpp | 2 +- src/lang/english.txt | 4 --- src/linkgraph/linkgraph_gui.cpp | 4 +-- src/misc_gui.cpp | 2 +- src/network/network_gui.cpp | 6 ++--- src/object_gui.cpp | 2 +- src/osk_gui.cpp | 2 +- src/rail_gui.cpp | 4 +-- src/road_gui.cpp | 12 ++++----- src/settings_gui.cpp | 10 +++---- src/signs_gui.cpp | 2 +- src/timetable_gui.cpp | 2 +- src/train_gui.cpp | 5 ++-- src/vehicle_gui.cpp | 2 +- 21 files changed, 78 insertions(+), 93 deletions(-) diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 30c8115cc6..39fc42deb8 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -328,8 +328,7 @@ public: case WID_AP_CLASS_DROPDOWN: { Dimension d = {0, 0}; for (uint i = 0; i < AirportClass::GetClassCount(); i++) { - SetDParam(0, AirportClass::Get((AirportClassID)i)->name); - d = maxdim(d, GetStringBoundingBox(STR_BLACK_STRING)); + d = maxdim(d, GetStringBoundingBox(AirportClass::Get((AirportClassID)i)->name)); } d.width += padding.width; d.height += padding.height; @@ -374,9 +373,7 @@ public: StringID string = GetAirportTextCallback(as, layout, CBID_AIRPORT_ADDITIONAL_TEXT); if (string == STR_UNDEFINED) continue; - /* STR_BLACK_STRING is used to start the string with {BLACK} */ - SetDParam(0, string); - Dimension d = GetStringMultiLineBoundingBox(STR_BLACK_STRING, *size); + Dimension d = GetStringMultiLineBoundingBox(string, *size); *size = maxdim(d, *size); } } @@ -417,8 +414,7 @@ public: const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index); StringID string = GetAirportTextCallback(as, _selected_airport_layout, CBID_AIRPORT_ADDITIONAL_TEXT); if (string != STR_UNDEFINED) { - SetDParam(0, string); - DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_BLACK_STRING); + DrawStringMultiLine(r.left, r.right, r.top, r.bottom, string, TC_BLACK); } } break; @@ -596,7 +592,7 @@ static const NWidgetPart _nested_build_airport_widgets[] = { EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(1, 0), SetPIP(2, 0, 2), NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_AIRPORT_CLASS_LABEL, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_AP_CLASS_DROPDOWN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_STATION_BUILD_AIRPORT_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_AP_CLASS_DROPDOWN), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_STATION_BUILD_AIRPORT_TOOLTIP), NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_AIRPORT_SPRITE), SetFill(1, 0), NWidget(NWID_HORIZONTAL), NWidget(WWT_MATRIX, COLOUR_GREY, WID_AP_AIRPORT_LIST), SetFill(1, 0), SetMatrixDataTip(1, 5, STR_STATION_BUILD_AIRPORT_TOOLTIP), SetScrollbar(WID_AP_SCROLLBAR), @@ -604,7 +600,7 @@ static const NWidgetPart _nested_build_airport_widgets[] = { EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_DECREASE), SetMinimalSize(12, 0), SetDataTip(AWV_DECREASE, STR_NULL), - NWidget(WWT_LABEL, COLOUR_GREY, WID_AP_LAYOUT_NUM), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NULL), + NWidget(WWT_LABEL, COLOUR_GREY, WID_AP_LAYOUT_NUM), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_NULL), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_AP_LAYOUT_INCREASE), SetMinimalSize(12, 0), SetDataTip(AWV_INCREASE, STR_NULL), EndContainer(), NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_EXTRA_TEXT), SetFill(1, 0), SetMinimalSize(150, 0), diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index c7c8603dc1..69fc99e44b 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -769,7 +769,7 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = { NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_RAIL_ROAD_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_JUST_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(), EndContainer(), diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index b9d8962564..ac5f854c0e 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -57,7 +57,7 @@ uint GetEngineListHeight(VehicleType type) static const NWidgetPart _nested_build_vehicle_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), - NWidget(WWT_CAPTION, COLOUR_GREY, WID_BV_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_BV_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE), NWidget(WWT_SHADEBOX, COLOUR_GREY), NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), NWidget(WWT_STICKYBOX, COLOUR_GREY), diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 99f3603014..59603e105f 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1148,9 +1148,9 @@ static const NWidgetPart _nested_select_company_livery_widgets [] = { EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_GREY, WID_SCL_SPACER_DROPDOWN), SetMinimalSize(150, 12), SetFill(1, 1), EndContainer(), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SCL_PRI_COL_DROPDOWN), SetMinimalSize(125, 12), SetFill(0, 1), SetDataTip(STR_BLACK_STRING, STR_LIVERY_PRIMARY_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SCL_PRI_COL_DROPDOWN), SetMinimalSize(125, 12), SetFill(0, 1), SetDataTip(STR_JUST_STRING, STR_LIVERY_PRIMARY_TOOLTIP), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_SCL_SEC_COL_DROPDOWN), SetMinimalSize(125, 12), SetFill(0, 1), - SetDataTip(STR_BLACK_STRING, STR_LIVERY_SECONDARY_TOOLTIP), + SetDataTip(STR_JUST_STRING, STR_LIVERY_SECONDARY_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_MATRIX, COLOUR_GREY, WID_SCL_MATRIX), SetMinimalSize(275, 0), SetResize(1, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_LIVERY_PANEL_TOOLTIP), SetScrollbar(WID_SCL_MATRIX_SCROLLBAR), @@ -1281,82 +1281,82 @@ static const NWidgetPart _nested_select_company_manager_face_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_EYECOLOUR, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_WHITE_STRING, STR_FACE_MOUSTACHE_EARRING_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_JUST_STRING, STR_FACE_MOUSTACHE_EARRING_TOOLTIP), SetTextStyle(TC_WHITE), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_GLASSES, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_WHITE_STRING, STR_FACE_GLASSES_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_JUST_STRING, STR_FACE_GLASSES_TOOLTIP), SetTextStyle(TC_WHITE), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_HAIR, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_L), SetDataTip(AWV_DECREASE, STR_FACE_HAIR_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetDataTip(STR_WHITE_STRING, STR_FACE_HAIR_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetDataTip(STR_JUST_STRING, STR_FACE_HAIR_TOOLTIP), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_R), SetDataTip(AWV_INCREASE, STR_FACE_HAIR_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_EYEBROWS, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_L), SetDataTip(AWV_DECREASE, STR_FACE_EYEBROWS_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetDataTip(STR_WHITE_STRING, STR_FACE_EYEBROWS_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetDataTip(STR_JUST_STRING, STR_FACE_EYEBROWS_TOOLTIP), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_R), SetDataTip(AWV_INCREASE, STR_FACE_EYEBROWS_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_EYECOLOUR, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_L), SetDataTip(AWV_DECREASE, STR_FACE_EYECOLOUR_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetDataTip(STR_WHITE_STRING, STR_FACE_EYECOLOUR_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetDataTip(STR_JUST_STRING, STR_FACE_EYECOLOUR_TOOLTIP), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_R), SetDataTip(AWV_INCREASE, STR_FACE_EYECOLOUR_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_GLASSES, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_L), SetDataTip(AWV_DECREASE, STR_FACE_GLASSES_TOOLTIP_2), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetDataTip(STR_WHITE_STRING, STR_FACE_GLASSES_TOOLTIP_2), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetDataTip(STR_JUST_STRING, STR_FACE_GLASSES_TOOLTIP_2), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_R), SetDataTip(AWV_INCREASE, STR_FACE_GLASSES_TOOLTIP_2), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_NOSE, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_L), SetDataTip(AWV_DECREASE, STR_FACE_NOSE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetDataTip(STR_WHITE_STRING, STR_FACE_NOSE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetDataTip(STR_JUST_STRING, STR_FACE_NOSE_TOOLTIP), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_R), SetDataTip(AWV_INCREASE, STR_FACE_NOSE_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_MOUSTACHE, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_L), SetDataTip(AWV_DECREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetDataTip(STR_WHITE_STRING, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetDataTip(STR_JUST_STRING, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_R), SetDataTip(AWV_INCREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_CHIN, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_L), SetDataTip(AWV_DECREASE, STR_FACE_CHIN_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetDataTip(STR_WHITE_STRING, STR_FACE_CHIN_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetDataTip(STR_JUST_STRING, STR_FACE_CHIN_TOOLTIP), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_R), SetDataTip(AWV_INCREASE, STR_FACE_CHIN_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_JACKET, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_L), SetDataTip(AWV_DECREASE, STR_FACE_JACKET_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetDataTip(STR_WHITE_STRING, STR_FACE_JACKET_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetDataTip(STR_JUST_STRING, STR_FACE_JACKET_TOOLTIP), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_R), SetDataTip(AWV_INCREASE, STR_FACE_JACKET_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_COLLAR, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_L), SetDataTip(AWV_DECREASE, STR_FACE_COLLAR_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetDataTip(STR_WHITE_STRING, STR_FACE_COLLAR_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetDataTip(STR_JUST_STRING, STR_FACE_COLLAR_TOOLTIP), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_R), SetDataTip(AWV_INCREASE, STR_FACE_COLLAR_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_EARRING, STR_NULL), SetTextStyle(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_L), SetDataTip(AWV_DECREASE, STR_FACE_TIE_EARRING_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetDataTip(STR_WHITE_STRING, STR_FACE_TIE_EARRING_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetDataTip(STR_JUST_STRING, STR_FACE_TIE_EARRING_TOOLTIP), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_R), SetDataTip(AWV_INCREASE, STR_FACE_TIE_EARRING_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetFill(0, 1), @@ -1927,8 +1927,7 @@ struct CompanyInfrastructureWindow : Window for (const auto &rt : _sorted_railtypes) { if (HasBit(this->railtypes, rt)) { lines++; - SetDParam(0, GetRailTypeInfo(rt)->strings.name); - size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WidgetDimensions::scaled.hsep_indent); + size->width = std::max(size->width, GetStringBoundingBox(GetRailTypeInfo(rt)->strings.name).width + WidgetDimensions::scaled.hsep_indent); } } if (this->railtypes != RAILTYPES_NONE) { @@ -1949,8 +1948,7 @@ struct CompanyInfrastructureWindow : Window for (const auto &rt : _sorted_roadtypes) { if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) { lines++; - SetDParam(0, GetRoadTypeInfo(rt)->strings.name); - size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WidgetDimensions::scaled.hsep_indent); + size->width = std::max(size->width, GetStringBoundingBox(GetRoadTypeInfo(rt)->strings.name).width + WidgetDimensions::scaled.hsep_indent); } } @@ -2056,8 +2054,7 @@ struct CompanyInfrastructureWindow : Window /* Draw name of each valid railtype. */ for (const auto &rt : _sorted_railtypes) { if (HasBit(this->railtypes, rt)) { - SetDParam(0, GetRailTypeInfo(rt)->strings.name); - DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, GetRailTypeInfo(rt)->strings.name, TC_WHITE); } } DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS); @@ -2089,8 +2086,7 @@ struct CompanyInfrastructureWindow : Window /* Draw name of each valid roadtype. */ for (const auto &rt : _sorted_roadtypes) { if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) { - SetDParam(0, GetRoadTypeInfo(rt)->strings.name); - DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, GetRoadTypeInfo(rt)->strings.name, TC_WHITE); } } diff --git a/src/framerate_gui.cpp b/src/framerate_gui.cpp index e4db1ee341..4727a587a5 100644 --- a/src/framerate_gui.cpp +++ b/src/framerate_gui.cpp @@ -739,7 +739,7 @@ static WindowDesc _framerate_display_desc( static const NWidgetPart _frametime_graph_window_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), - NWidget(WWT_CAPTION, COLOUR_GREY, WID_FGW_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_FGW_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE), NWidget(WWT_STICKYBOX, COLOUR_GREY), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 8db9771e04..962e1a4a56 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -160,7 +160,7 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_JUST_DATE_LONG, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1), EndContainer(), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_JUST_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), @@ -304,7 +304,7 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_JUST_DATE_LONG, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1), EndContainer(), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_JUST_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index bdf9d3fca6..4cbafd650d 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -417,16 +417,16 @@ static const NWidgetPart _nested_goal_question_widgets_question[] = { NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetPadding(8, 8, 8, 8), SetFill(1, 0), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, 10, 85), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, 10, 65), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, 10, 25), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_3), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_3), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTON_SPACER), @@ -444,16 +444,16 @@ static const NWidgetPart _nested_goal_question_widgets_info[] = { NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetPadding(8, 8, 8, 8), SetFill(1, 0), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, 10, 85), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, 10, 65), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, 10, 25), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_3), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_3), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTON_SPACER), @@ -471,16 +471,16 @@ static const NWidgetPart _nested_goal_question_widgets_warning[] = { NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetPadding(8, 8, 8, 8), SetFill(1, 0), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, 10, 85), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, 10, 65), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, 10, 25), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_3), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_3), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTON_SPACER), @@ -498,16 +498,16 @@ static const NWidgetPart _nested_goal_question_widgets_error[] = { NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetPadding(8, 8, 8, 8), SetFill(1, 0), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, 10, 85), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, 10, 65), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, 10, 25), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_3), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_3), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTON_SPACER), diff --git a/src/group_gui.cpp b/src/group_gui.cpp index ec6c60de9d..429a25e49e 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -96,7 +96,7 @@ static const NWidgetPart _nested_group_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(1, 0), SetFill(1, 1), SetResize(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_AVAILABLE_VEHICLES), SetMinimalSize(106, 12), - SetDataTip(STR_BLACK_STRING, STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP), + SetDataTip(STR_JUST_STRING, STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP), NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetResize(1, 0), EndContainer(), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_MANAGE_VEHICLES_DROPDOWN), SetMinimalSize(118, 12), SetDataTip(STR_VEHICLE_LIST_MANAGE_LIST, STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP), diff --git a/src/lang/english.txt b/src/lang/english.txt index c205d6fa08..d3054b4420 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5611,11 +5611,7 @@ STR_SHORT_DATE :{WHITE}{DATE_TI STR_TINY_GROUP :{TINY_FONT}{GROUP} STR_WHITE_SIGN :{WHITE}{SIGN} STR_TINY_BLACK_STATION :{TINY_FONT}{BLACK}{STATION} -STR_BLACK_STRING :{BLACK}{STRING} STR_BLACK_RAW_STRING :{BLACK}{RAW_STRING} -STR_ORANGE_STRING :{ORANGE}{STRING} -STR_LTBLUE_STRING :{LTBLUE}{STRING} -STR_WHITE_STRING :{WHITE}{STRING} STR_ORANGE_STRING1_WHITE :{ORANGE}{STRING1}{WHITE} STR_ORANGE_STRING1_LTBLUE :{ORANGE}{STRING1}{LTBLUE} STR_TINY_BLACK_HEIGHT :{TINY_FONT}{BLACK}{HEIGHT} diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 3676a9cb0f..ad6415e91e 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -657,9 +657,7 @@ bool LinkGraphLegendWindow::OnTooltip(Point pt, int widget, TooltipCloseConditio if (IsInsideMM(widget, WID_LGL_CARGO_FIRST, WID_LGL_CARGO_LAST + 1)) { if (this->IsWidgetDisabled(widget)) return false; CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST); - uint64 params[1]; - params[0] = cargo->name; - GuiShowTooltips(this, STR_BLACK_STRING, 1, params, close_cond); + GuiShowTooltips(this, cargo->name, 0, nullptr, close_cond); return true; } return false; diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index ad2e9d7b4e..a730dfafe7 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -1072,7 +1072,7 @@ struct QueryStringWindow : public Window static const NWidgetPart _nested_query_string_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), - NWidget(WWT_CAPTION, COLOUR_GREY, WID_QS_CAPTION), SetDataTip(STR_WHITE_STRING, STR_NULL), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_QS_CAPTION), SetDataTip(STR_JUST_STRING, STR_NULL), SetTextStyle(TC_WHITE), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_EDITBOX, COLOUR_GREY, WID_QS_TEXT), SetMinimalSize(256, 12), SetFill(1, 1), SetPadding(2, 2, 2, 2), diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 5c0e21936d..3d26a54d49 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1227,7 +1227,7 @@ static const NWidgetPart _nested_network_start_server_window_widgets[] = { NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 6, 10), NWidget(NWID_VERTICAL), SetPIP(0, 1, 0), NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_LABEL), SetFill(1, 0), SetDataTip(STR_NETWORK_START_SERVER_VISIBILITY_LABEL, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_BTN), SetFill(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_LIGHT_BLUE, WID_NSS_CONNTYPE_BTN), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP), EndContainer(), NWidget(NWID_VERTICAL), SetPIP(0, 1, 0), NWidget(NWID_SPACER), SetFill(1, 1), @@ -1317,7 +1317,7 @@ static const NWidgetPart _nested_client_list_widgets[] = { NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY, STR_NULL), NWidget(NWID_SPACER), SetMinimalSize(10, 0), SetFill(1, 0), SetResize(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_CL_SERVER_VISIBILITY), SetDataTip(STR_BLACK_STRING, STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_CL_SERVER_VISIBILITY), SetDataTip(STR_JUST_STRING, STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE, STR_NULL), @@ -1327,7 +1327,7 @@ static const NWidgetPart _nested_client_list_widgets[] = { NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE, STR_NULL), NWidget(NWID_SPACER), SetMinimalSize(10, 0), - NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_CONNECTION_TYPE), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_STRING, STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT), + NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_CONNECTION_TYPE), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_JUST_STRING, STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT), EndContainer(), EndContainer(), EndContainer(), diff --git a/src/object_gui.cpp b/src/object_gui.cpp index a644becaa6..414d930e5d 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -706,7 +706,7 @@ static const NWidgetPart _nested_build_object_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY, WID_BO_OBJECT_SPRITE), SetDataTip(0x0, STR_OBJECT_BUILD_PREVIEW_TOOLTIP), EndContainer(), EndContainer(), EndContainer(), - NWidget(WWT_TEXT, COLOUR_DARK_GREEN, WID_BO_OBJECT_NAME), SetDataTip(STR_ORANGE_STRING, STR_NULL), + NWidget(WWT_TEXT, COLOUR_DARK_GREEN, WID_BO_OBJECT_NAME), SetDataTip(STR_JUST_STRING, STR_NULL), SetTextStyle(TC_ORANGE), NWidget(WWT_TEXT, COLOUR_DARK_GREEN, WID_BO_OBJECT_SIZE), SetDataTip(STR_OBJECT_BUILD_SIZE, STR_NULL), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BO_SELECT_SCROLL), diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp index 72e2ae169c..1cfbfc8ace 100644 --- a/src/osk_gui.cpp +++ b/src/osk_gui.cpp @@ -325,7 +325,7 @@ static NWidgetBase *MakeSpacebarKeys(int *biggest_index) static const NWidgetPart _nested_osk_widgets[] = { - NWidget(WWT_CAPTION, COLOUR_GREY, WID_OSK_CAPTION), SetDataTip(STR_WHITE_STRING, STR_NULL), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_OSK_CAPTION), SetDataTip(STR_JUST_STRING, STR_NULL), SetTextStyle(TC_WHITE), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_EDITBOX, COLOUR_GREY, WID_OSK_TEXT), SetMinimalSize(252, 12), SetPadding(2, 2, 2, 2), EndContainer(), diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index d72675e054..71f7bd5a8a 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -799,7 +799,7 @@ HotkeyList BuildRailToolbarWindow::hotkeys("railtoolbar", railtoolbar_hotkeys, R static const NWidgetPart _nested_build_rail_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), - NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_RAT_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_RAT_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE), NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -1574,7 +1574,7 @@ static const NWidgetPart _nested_station_builder_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY, WID_BRAS_PLATFORM_DIR_Y), SetMinimalSize(66, 60), SetFill(0, 0), SetDataTip(0x0, STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(7, 0), SetFill(1, 0), EndContainer(), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BRAS_SHOW_NEWST_TYPE), SetMinimalSize(144, 11), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(1, 2, 4, 2), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BRAS_SHOW_NEWST_TYPE), SetMinimalSize(144, 11), SetDataTip(STR_JUST_STRING, STR_NULL), SetTextStyle(TC_ORANGE), SetPadding(1, 2, 4, 2), NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_NUMBER_OF_TRACKS, STR_NULL), SetPadding(0, 2, 0, 2), NWidget(NWID_HORIZONTAL), NWidget(NWID_SPACER), SetFill(1, 0), diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 50660c277b..2dc7ec39f9 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -830,7 +830,7 @@ HotkeyList BuildRoadToolbarWindow::tram_hotkeys("tramtoolbar", tramtoolbar_hotke static const NWidgetPart _nested_build_road_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), - NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE), NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -873,7 +873,7 @@ static WindowDesc _build_road_desc( static const NWidgetPart _nested_build_tramway_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), - NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE), NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -932,7 +932,7 @@ Window *ShowBuildRoadToolbar(RoadType roadtype) static const NWidgetPart _nested_build_road_scen_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), - NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE), NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -969,7 +969,7 @@ static WindowDesc _build_road_scen_desc( static const NWidgetPart _nested_build_tramway_scen_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), - NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE), NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -1655,7 +1655,7 @@ static const NWidgetPart _nested_road_station_picker_widgets[] = { NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_TYPE_SEL), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_SHOW_NEWST_TYPE), SetMinimalSize(144, 8), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(4, 2, 4, 2), SetFill(1, 0), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_SHOW_NEWST_TYPE), SetMinimalSize(144, 8), SetDataTip(STR_JUST_STRING, STR_NULL), SetTextStyle(TC_ORANGE), SetPadding(4, 2, 4, 2), SetFill(1, 0), EndContainer(), NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 0), NWidget(NWID_HORIZONTAL), @@ -1740,7 +1740,7 @@ static const NWidgetPart _nested_tram_station_picker_widgets[] = { NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_TYPE_SEL), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_SHOW_NEWST_TYPE), SetMinimalSize(144, 8), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(4, 2, 4, 2), SetFill(1, 0), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_SHOW_NEWST_TYPE), SetMinimalSize(144, 8), SetDataTip(STR_JUST_STRING, STR_NULL), SetTextStyle(TC_ORANGE), SetPadding(4, 2, 4, 2), SetFill(1, 0), EndContainer(), NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 0), NWidget(NWID_HORIZONTAL), diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index bd5ac49630..37479c9e4a 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -735,11 +735,11 @@ static const NWidgetPart _nested_game_options_widgets[] = { EndContainer(), NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_AUTOSAVE_FRAME, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_AUTOSAVE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_AUTOSAVE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING, STR_GAME_OPTIONS_AUTOSAVE_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(100, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0), EndContainer(), EndContainer(), @@ -766,7 +766,7 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12),SetDataTip(STR_GAME_OPTIONS_RESOLUTION, STR_NULL), NWidget(NWID_SPACER), SetMinimalSize(1, 0), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_RESOLUTION_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING, STR_GAME_OPTIONS_RESOLUTION_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetDataTip(STR_GAME_OPTIONS_REFRESH_RATE, STR_NULL), @@ -2562,11 +2562,11 @@ static const NWidgetPart _nested_settings_selection_widgets[] = { NWidget(NWID_VERTICAL), SetPIP(WidgetDimensions::unscaled.frametext.top, WidgetDimensions::unscaled.vsep_normal, WidgetDimensions::unscaled.frametext.bottom), NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.hsep_wide, WidgetDimensions::unscaled.frametext.right), NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_CATEGORY), SetDataTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_RESTRICT_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_RESTRICT_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING, STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.hsep_wide, WidgetDimensions::unscaled.frametext.right), NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_TYPE), SetDataTip(STR_CONFIG_SETTING_RESTRICT_TYPE, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_STRING, STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.hsep_wide, WidgetDimensions::unscaled.frametext.right), NWidget(WWT_TEXT, COLOUR_MAUVE), SetFill(0, 1), SetDataTip(STR_CONFIG_SETTING_FILTER_TITLE, STR_NULL), diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 6ee257b996..925956b93f 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -539,7 +539,7 @@ struct SignWindow : Window, SignList { static const NWidgetPart _nested_query_sign_edit_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), - NWidget(WWT_CAPTION, COLOUR_GREY, WID_QES_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_QES_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), SetTextStyle(TC_WHITE), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_QES_LOCATION), SetMinimalSize(12, 14), SetDataTip(SPR_GOTO_LOCATION, STR_EDIT_SIGN_LOCATION_TOOLTIP), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index d803ca4537..2f924f3cf1 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -747,7 +747,7 @@ static const NWidgetPart _nested_timetable_widgets[] = { NWidget(NWID_VERTICAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_AUTOFILL), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_AUTOFILL, STR_TIMETABLE_AUTOFILL_TOOLTIP), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VT_EXPECTED_SELECTION), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_EXPECTED), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_BLACK_STRING, STR_TIMETABLE_EXPECTED_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_EXPECTED), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_JUST_STRING, STR_TIMETABLE_EXPECTED_TOOLTIP), NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(), EndContainer(), EndContainer(), diff --git a/src/train_gui.cpp b/src/train_gui.cpp index e6a3d0f135..5a44282d44 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -209,11 +209,10 @@ static void TrainDetailsCargoTab(const CargoSummaryItem *item, int left, int rig SetDParam(3, _settings_game.vehicle.freight_trains); str = FreightWagonMult(item->cargo) > 1 ? STR_VEHICLE_DETAILS_CARGO_FROM_MULT : STR_VEHICLE_DETAILS_CARGO_FROM; } else { - SetDParam(0, STR_QUANTITY_N_A); - str = item->cargo == INVALID_CARGO ? STR_LTBLUE_STRING : STR_VEHICLE_DETAILS_CARGO_EMPTY; + str = item->cargo == INVALID_CARGO ? STR_QUANTITY_N_A : STR_VEHICLE_DETAILS_CARGO_EMPTY; } - DrawString(left, right, y, str); + DrawString(left, right, y, str, TC_LIGHT_BLUE); } /** diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index bbde5852db..32ec4c55b6 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1532,7 +1532,7 @@ static const NWidgetPart _nested_vehicle_list[] = { NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VL_HIDE_BUTTONS), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_AVAILABLE_VEHICLES), SetMinimalSize(106, 12), SetFill(0, 1), - SetDataTip(STR_BLACK_STRING, STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP), + SetDataTip(STR_JUST_STRING, STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP), NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetResize(1, 0), SetFill(1, 1), EndContainer(), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_MANAGE_VEHICLES_DROPDOWN), SetMinimalSize(118, 12), SetFill(0, 1), SetDataTip(STR_VEHICLE_LIST_MANAGE_LIST, STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP), From 61407840c67c1f38ffa31b2141c634aa8945d9ac Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 25 Apr 2023 18:01:58 +0100 Subject: [PATCH 29/34] Codechange: Remove STR_BLACK_RAW_STRING. --- src/lang/english.txt | 1 - src/league_gui.cpp | 2 +- src/misc_gui.cpp | 2 +- src/network/network_gui.cpp | 6 +++--- src/newgrf_gui.cpp | 2 +- src/settings_gui.cpp | 20 ++++++++++---------- src/story_gui.cpp | 6 +++--- 7 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index d3054b4420..a26c48069d 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5611,7 +5611,6 @@ STR_SHORT_DATE :{WHITE}{DATE_TI STR_TINY_GROUP :{TINY_FONT}{GROUP} STR_WHITE_SIGN :{WHITE}{SIGN} STR_TINY_BLACK_STATION :{TINY_FONT}{BLACK}{STATION} -STR_BLACK_RAW_STRING :{BLACK}{RAW_STRING} STR_ORANGE_STRING1_WHITE :{ORANGE}{STRING1}{WHITE} STR_ORANGE_STRING1_LTBLUE :{ORANGE}{STRING1}{LTBLUE} STR_TINY_BLACK_HEIGHT :{TINY_FONT}{BLACK}{HEIGHT} diff --git a/src/league_gui.cpp b/src/league_gui.cpp index a46cd2efa6..ec1e828178 100644 --- a/src/league_gui.cpp +++ b/src/league_gui.cpp @@ -421,7 +421,7 @@ public: static const NWidgetPart _nested_script_league_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), - NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SLT_CAPTION), SetDataTip(STR_BLACK_RAW_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SLT_CAPTION), SetDataTip(STR_JUST_RAW_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_SHADEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), EndContainer(), diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index a730dfafe7..351fd087e4 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -388,7 +388,7 @@ static const NWidgetPart _nested_about_widgets[] = { NWidget(WWT_FRAME, COLOUR_GREY), SetPadding(0, 5, 1, 5), NWidget(WWT_EMPTY, INVALID_COLOUR, WID_A_SCROLLING_TEXT), EndContainer(), - NWidget(WWT_LABEL, COLOUR_GREY, WID_A_WEBSITE), SetDataTip(STR_BLACK_RAW_STRING, STR_NULL), + NWidget(WWT_LABEL, COLOUR_GREY, WID_A_WEBSITE), SetDataTip(STR_JUST_RAW_STRING, STR_NULL), NWidget(WWT_LABEL, COLOUR_GREY, WID_A_COPYRIGHT), SetDataTip(STR_ABOUT_COPYRIGHT_OPENTTD, STR_NULL), EndContainer(), }; diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 3d26a54d49..63f2284247 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1309,7 +1309,7 @@ static const NWidgetPart _nested_client_list_widgets[] = { NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_NAME, STR_NULL), NWidget(NWID_SPACER), SetMinimalSize(10, 0), - NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_NAME), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_RAW_STRING, STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT), + NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_NAME), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_JUST_RAW_STRING, STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_CL_SERVER_NAME_EDIT), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CL_SERVER_SELECTOR), @@ -1322,7 +1322,7 @@ static const NWidgetPart _nested_client_list_widgets[] = { NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE, STR_NULL), NWidget(NWID_SPACER), SetMinimalSize(10, 0), - NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_INVITE_CODE), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_RAW_STRING, STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT), + NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_SERVER_INVITE_CODE), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_JUST_RAW_STRING, STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT), EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE, STR_NULL), @@ -1336,7 +1336,7 @@ static const NWidgetPart _nested_client_list_widgets[] = { NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalTextLines(1, 0), SetDataTip(STR_NETWORK_CLIENT_LIST_PLAYER_NAME, STR_NULL), NWidget(NWID_SPACER), SetMinimalSize(10, 0), - NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_CLIENT_NAME), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_BLACK_RAW_STRING, STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT), + NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_CLIENT_NAME), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetDataTip(STR_JUST_RAW_STRING, STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_CL_CLIENT_NAME_EDIT), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP), EndContainer(), EndContainer(), diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 63a326a975..f4fb441dd7 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -140,7 +140,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params) /* Draw GRF info if it exists */ if (!StrEmpty(c->GetDescription())) { SetDParamStr(0, c->GetDescription()); - tr.top = DrawStringMultiLine(tr, STR_BLACK_RAW_STRING); + tr.top = DrawStringMultiLine(tr, STR_JUST_RAW_STRING, TC_BLACK); } else { tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_NO_INFO); } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 37479c9e4a..98a87b09d6 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -333,17 +333,17 @@ struct GameOptionsWindow : Window { switch (widget) { case WID_GO_BASE_GRF_DESCRIPTION: SetDParamStr(0, BaseGraphics::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode())); - DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING); + DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); break; case WID_GO_BASE_SFX_DESCRIPTION: SetDParamStr(0, BaseSounds::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode())); - DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING); + DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); break; case WID_GO_BASE_MUSIC_DESCRIPTION: SetDParamStr(0, BaseMusic::GetUsedSet()->GetDescription(GetCurrentLanguageIsoCode())); - DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING); + DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); break; case WID_GO_GUI_SCALE: @@ -385,7 +385,7 @@ struct GameOptionsWindow : Window { int y = 0; for (int i = 0; i < BaseGraphics::GetNumSets(); i++) { SetDParamStr(0, BaseGraphics::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode())); - y = std::max(y, GetStringHeight(STR_BLACK_RAW_STRING, wid->current_x)); + y = std::max(y, GetStringHeight(STR_JUST_RAW_STRING, wid->current_x)); } changed |= wid->UpdateVerticalSize(y); @@ -393,7 +393,7 @@ struct GameOptionsWindow : Window { y = 0; for (int i = 0; i < BaseSounds::GetNumSets(); i++) { SetDParamStr(0, BaseSounds::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode())); - y = std::max(y, GetStringHeight(STR_BLACK_RAW_STRING, wid->current_x)); + y = std::max(y, GetStringHeight(STR_JUST_RAW_STRING, wid->current_x)); } changed |= wid->UpdateVerticalSize(y); @@ -401,7 +401,7 @@ struct GameOptionsWindow : Window { y = 0; for (int i = 0; i < BaseMusic::GetNumSets(); i++) { SetDParamStr(0, BaseMusic::GetSet(i)->GetDescription(GetCurrentLanguageIsoCode())); - y = std::max(y, GetStringHeight(STR_BLACK_RAW_STRING, wid->current_x)); + y = std::max(y, GetStringHeight(STR_JUST_RAW_STRING, wid->current_x)); } changed |= wid->UpdateVerticalSize(y); @@ -731,7 +731,7 @@ static const NWidgetPart _nested_game_options_widgets[] = { /* General tab */ NWidget(NWID_VERTICAL), SetPadding(10), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_LANGUAGE, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_LANG_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_LANGUAGE_TOOLTIP), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_LANG_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_GAME_OPTIONS_LANGUAGE_TOOLTIP), SetFill(1, 0), EndContainer(), NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_AUTOSAVE_FRAME, STR_NULL), @@ -798,7 +798,7 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_GRF, STR_NULL), NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 0), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_GRF_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_GAME_OPTIONS_BASE_GRF_TOOLTIP), NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_STATUS), SetMinimalSize(100, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_GRF_DESCRIPTION), SetMinimalSize(200, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), @@ -827,7 +827,7 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_SFX, STR_NULL), NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 7), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_SFX_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_SFX_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_GAME_OPTIONS_BASE_SFX_TOOLTIP), NWidget(NWID_SPACER), SetMinimalSize(100, 12), SetFill(1, 0), EndContainer(), NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GO_BASE_SFX_DESCRIPTION), SetMinimalSize(200, 0), SetMinimalTextLines(1, 0), SetDataTip(STR_NULL, STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), @@ -840,7 +840,7 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_BASE_MUSIC, STR_NULL), NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 7), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_BASE_MUSIC_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_JUST_RAW_STRING, STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP), NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_STATUS), SetMinimalSize(100, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 7), diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 16dbe9a640..b96ef35e4c 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -333,7 +333,7 @@ protected: switch (pe.type) { case SPET_TEXT: SetDParamStr(0, pe.text); - return GetStringHeight(STR_BLACK_RAW_STRING, max_width); + return GetStringHeight(STR_JUST_RAW_STRING, max_width); case SPET_GOAL: case SPET_LOCATION: { @@ -778,7 +778,7 @@ public: } else { SetDParamStr(0, this->selected_generic_title); } - Dimension title_d = GetStringBoundingBox(STR_BLACK_RAW_STRING); + Dimension title_d = GetStringBoundingBox(STR_JUST_RAW_STRING); if (title_d.width > d.width) { d.width = title_d.width; @@ -969,7 +969,7 @@ static const NWidgetPart _nested_story_book_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SB_PREV_PAGE), SetMinimalSize(100, 0), SetFill(0, 0), SetDataTip(STR_STORY_BOOK_PREV_PAGE, STR_STORY_BOOK_PREV_PAGE_TOOLTIP), NWidget(NWID_BUTTON_DROPDOWN, COLOUR_BROWN, WID_SB_SEL_PAGE), SetMinimalSize(93, 12), SetFill(1, 0), - SetDataTip(STR_BLACK_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0), + SetDataTip(STR_JUST_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0), NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SB_NEXT_PAGE), SetMinimalSize(100, 0), SetFill(0, 0), SetDataTip(STR_STORY_BOOK_NEXT_PAGE, STR_STORY_BOOK_NEXT_PAGE_TOOLTIP), NWidget(WWT_RESIZEBOX, COLOUR_BROWN), EndContainer(), From 49eb6385631ebfe9b76bff3a82f4f4d255f34e6e Mon Sep 17 00:00:00 2001 From: glx22 Date: Fri, 28 Apr 2023 01:24:04 +0200 Subject: [PATCH 30/34] Codechange: Remove STR_ORANGE_STRING1_WHITE and STR_ORANGE_STRING1_LTBLUE. --- src/lang/english.txt | 3 +-- src/settings_gui.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index a26c48069d..25e9cef569 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1170,6 +1170,7 @@ STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Expand a STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Collapse all STR_CONFIG_SETTING_RESET_ALL :{BLACK}Reset all values STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(no explanation available) +STR_CONFIG_SETTING_VALUE :{PUSH_COLOUR}{ORANGE}{STRING1}{POP_COLOUR} STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}Default value: {ORANGE}{STRING1} STR_CONFIG_SETTING_TYPE :{LTBLUE}Setting type: {ORANGE}{STRING} STR_CONFIG_SETTING_TYPE_CLIENT :Client setting (not stored in saves; affects all games) @@ -5611,8 +5612,6 @@ STR_SHORT_DATE :{WHITE}{DATE_TI STR_TINY_GROUP :{TINY_FONT}{GROUP} STR_WHITE_SIGN :{WHITE}{SIGN} STR_TINY_BLACK_STATION :{TINY_FONT}{BLACK}{STATION} -STR_ORANGE_STRING1_WHITE :{ORANGE}{STRING1}{WHITE} -STR_ORANGE_STRING1_LTBLUE :{ORANGE}{STRING1}{LTBLUE} STR_TINY_BLACK_HEIGHT :{TINY_FONT}{BLACK}{HEIGHT} STR_TINY_BLACK_VEHICLE :{TINY_FONT}{BLACK}{VEHICLE} STR_TINY_RIGHT_ARROW :{TINY_FONT}{RIGHT_ARROW} diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 98a87b09d6..1be6742b92 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1324,7 +1324,7 @@ void SettingEntry::DrawSetting(GameSettings *settings_ptr, int left, int right, /* We do not allow changes of some items when we are a client in a networkgame */ bool editable = sd->IsEditable(); - SetDParam(0, highlight ? STR_ORANGE_STRING1_WHITE : STR_ORANGE_STRING1_LTBLUE); + SetDParam(0, STR_CONFIG_SETTING_VALUE); int32 value = sd->Read(ResolveObject(settings_ptr, sd)); if (sd->IsBoolSetting()) { /* Draw checkbox for boolean-value either on/off */ From 999057a4d8662ce6589ac3c78101ec131b00f4ef Mon Sep 17 00:00:00 2001 From: glx22 Date: Fri, 28 Apr 2023 14:40:07 +0200 Subject: [PATCH 31/34] Codechange: Remove STR_SHORT_DATE --- src/lang/english.txt | 1 - src/news_gui.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 25e9cef569..769fc78427 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5608,7 +5608,6 @@ STR_JUST_RAW_STRING :{RAW_STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{RAW_STRING} # Slightly 'raw' stringcodes with colour or size -STR_SHORT_DATE :{WHITE}{DATE_TINY} STR_TINY_GROUP :{TINY_FONT}{GROUP} STR_WHITE_SIGN :{WHITE}{SIGN} STR_TINY_BLACK_STATION :{TINY_FONT}{BLACK}{STATION} diff --git a/src/news_gui.cpp b/src/news_gui.cpp index bfd8e67914..0a920ecd95 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -1155,7 +1155,7 @@ struct MessageHistoryWindow : Window { /* Months are off-by-one, so it's actually 8. Not using * month 12 because the 1 is usually less wide. */ SetDParam(0, TimerGameCalendar::ConvertYMDToDate(ORIGINAL_MAX_YEAR, 7, 30)); - this->date_width = GetStringBoundingBox(STR_SHORT_DATE).width + WidgetDimensions::scaled.hsep_wide; + this->date_width = GetStringBoundingBox(STR_JUST_DATE_TINY).width + WidgetDimensions::scaled.hsep_wide; size->height = 4 * resize->height + WidgetDimensions::scaled.framerect.Vertical(); // At least 4 lines are visible. size->width = std::max(200u, size->width); // At least 200 pixels wide. @@ -1186,7 +1186,7 @@ struct MessageHistoryWindow : Window { int y = news.top; for (int n = this->vscroll->GetCapacity(); n > 0; n--) { SetDParam(0, ni->date); - DrawString(date.left, date.right, y, STR_SHORT_DATE); + DrawString(date.left, date.right, y, STR_JUST_DATE_TINY, TC_WHITE); DrawNewsString(news.left, news.right, y, TC_WHITE, ni); y += this->line_height; From b2a36ff3ccdbe5da845d5f7ce35538fdf6cf5b7f Mon Sep 17 00:00:00 2001 From: glx22 Date: Fri, 28 Apr 2023 15:17:34 +0200 Subject: [PATCH 32/34] Codechange: Remove STR_TINY_GROUP and STR_TINY_BLACK_VEHICLE --- src/lang/english.txt | 6 ++---- src/vehicle_gui.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 769fc78427..a331a7032f 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3828,8 +3828,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Send ins STR_VEHICLE_LIST_REPLACE_VEHICLES :Replace vehicles STR_VEHICLE_LIST_SEND_FOR_SERVICING :Send for Servicing STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Profit this year: {CURRENCY_LONG} (last year: {CURRENCY_LONG}) -STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] -STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING1} {STRING1} +STR_VEHICLE_LIST_CARGO :[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{STRING1} {STRING1} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Send to Depot STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Send to Depot @@ -5608,11 +5608,9 @@ STR_JUST_RAW_STRING :{RAW_STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{RAW_STRING} # Slightly 'raw' stringcodes with colour or size -STR_TINY_GROUP :{TINY_FONT}{GROUP} STR_WHITE_SIGN :{WHITE}{SIGN} STR_TINY_BLACK_STATION :{TINY_FONT}{BLACK}{STATION} STR_TINY_BLACK_HEIGHT :{TINY_FONT}{BLACK}{HEIGHT} -STR_TINY_BLACK_VEHICLE :{TINY_FONT}{BLACK}{VEHICLE} STR_TINY_RIGHT_ARROW :{TINY_FONT}{RIGHT_ARROW} STR_BLACK_1 :{BLACK}1 diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 32ec4c55b6..c7642d9484 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1692,31 +1692,31 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int if (!v->name.empty()) { /* The vehicle got a name so we will print it and the cargoes */ - SetDParam(0, STR_TINY_BLACK_VEHICLE); + SetDParam(0, STR_VEHICLE_NAME); SetDParam(1, v->index); SetDParam(2, STR_VEHICLE_LIST_CARGO); SetDParam(3, vehicle_cargoes); - DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_NAME_AND_CARGO); + DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_NAME_AND_CARGO, TC_BLACK, SA_LEFT, false, FS_SMALL); } else if (v->group_id != DEFAULT_GROUP) { /* The vehicle has no name, but is member of a group, so print group name and the cargoes */ - SetDParam(0, STR_TINY_GROUP); + SetDParam(0, STR_GROUP_NAME); SetDParam(1, v->group_id); SetDParam(2, STR_VEHICLE_LIST_CARGO); SetDParam(3, vehicle_cargoes); - DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_NAME_AND_CARGO); + DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_NAME_AND_CARGO, TC_BLACK, SA_LEFT, false, FS_SMALL); } else { /* The vehicle has no name, and is not a member of a group, so just print the cargoes */ SetDParam(0, vehicle_cargoes); - DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_CARGO); + DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_CARGO, TC_BLACK, SA_LEFT, false, FS_SMALL); } } else if (!v->name.empty()) { /* The vehicle got a name so we will print it */ SetDParam(0, v->index); - DrawString(tr.left, tr.right, ir.top, STR_TINY_BLACK_VEHICLE); + DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_NAME, TC_BLACK, SA_LEFT, false, FS_SMALL); } else if (v->group_id != DEFAULT_GROUP) { /* The vehicle has no name, but is member of a group, so print group name */ SetDParam(0, v->group_id); - DrawString(tr.left, tr.right, ir.top, STR_TINY_GROUP, TC_BLACK); + DrawString(tr.left, tr.right, ir.top, STR_GROUP_NAME, TC_BLACK, SA_LEFT, false, FS_SMALL); } if (show_orderlist) DrawSmallOrderList(v, olr.left, olr.right, ir.top, this->order_arrow_width, v->cur_real_order_index); From 222e37d3196e7e8e34bd1095bdb93f562b808b26 Mon Sep 17 00:00:00 2001 From: glx22 Date: Fri, 28 Apr 2023 16:42:58 +0200 Subject: [PATCH 33/34] Codechange: Remove TINY_BLACK_STATION --- src/lang/english.txt | 1 - src/vehicle_gui.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index a331a7032f..5c1d63fbb0 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5609,7 +5609,6 @@ STR_JUST_BIG_RAW_STRING :{BIG_FONT}{RAW_ # Slightly 'raw' stringcodes with colour or size STR_WHITE_SIGN :{WHITE}{SIGN} -STR_TINY_BLACK_STATION :{TINY_FONT}{BLACK}{STATION} STR_TINY_BLACK_HEIGHT :{TINY_FONT}{BLACK}{HEIGHT} STR_TINY_RIGHT_ARROW :{TINY_FONT}{RIGHT_ARROW} diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index c7642d9484..6a90b7833b 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1564,7 +1564,7 @@ static void DrawSmallOrderList(const Vehicle *v, int left, int right, int y, uin if (order->IsType(OT_GOTO_STATION)) { SetDParam(0, order->GetDestination()); - DrawString(left + l_offset, right - r_offset, y, STR_TINY_BLACK_STATION); + DrawString(left + l_offset, right - r_offset, y, STR_STATION_NAME, TC_BLACK, SA_LEFT, false, FS_SMALL); y += FONT_HEIGHT_SMALL; if (++i == 4) break; @@ -1589,7 +1589,7 @@ static void DrawSmallOrderList(const Order *order, int left, int right, int y, u while (order != nullptr) { if (order->IsType(OT_GOTO_STATION)) { SetDParam(0, order->GetDestination()); - DrawString(left + l_offset, right - r_offset, y, STR_TINY_BLACK_STATION); + DrawString(left + l_offset, right - r_offset, y, STR_STATION_NAME, TC_BLACK, SA_LEFT, false, FS_SMALL); y += FONT_HEIGHT_SMALL; if (++i == 4) break; From 045a99dd23c5febd99c85ff5edec65e71b6eb75a Mon Sep 17 00:00:00 2001 From: glx22 Date: Fri, 28 Apr 2023 17:02:34 +0200 Subject: [PATCH 34/34] Codechange: Remove STR_TINY_RIGHT_ARROW --- src/lang/english.txt | 2 +- src/vehicle_gui.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 5c1d63fbb0..39f58b6ac1 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5591,6 +5591,7 @@ STR_VEHICLE_NAME :{VEHICLE} STR_WAYPOINT_NAME :{WAYPOINT} STR_JUST_CARGO :{CARGO_LONG} +STR_JUST_RIGHT_ARROW :{RIGHT_ARROW} STR_JUST_CHECKMARK :{CHECKMARK} STR_JUST_COMMA :{COMMA} STR_JUST_CURRENCY_SHORT :{CURRENCY_SHORT} @@ -5610,7 +5611,6 @@ STR_JUST_BIG_RAW_STRING :{BIG_FONT}{RAW_ # Slightly 'raw' stringcodes with colour or size STR_WHITE_SIGN :{WHITE}{SIGN} STR_TINY_BLACK_HEIGHT :{TINY_FONT}{BLACK}{HEIGHT} -STR_TINY_RIGHT_ARROW :{TINY_FONT}{RIGHT_ARROW} STR_BLACK_1 :{BLACK}1 STR_BLACK_2 :{BLACK}2 diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 6a90b7833b..384357137b 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -363,7 +363,7 @@ Dimension BaseVehicleListWindow::GetActionDropdownSize(bool show_autoreplace, bo void BaseVehicleListWindow::OnInit() { - this->order_arrow_width = GetStringBoundingBox(STR_TINY_RIGHT_ARROW).width; + this->order_arrow_width = GetStringBoundingBox(STR_JUST_RIGHT_ARROW, FS_SMALL).width; this->SetCargoFilterArray(); } @@ -1560,7 +1560,7 @@ static void DrawSmallOrderList(const Vehicle *v, int left, int right, int y, uin VehicleOrderID oid = start; do { - if (oid == v->cur_real_order_index) DrawString(left, right, y, STR_TINY_RIGHT_ARROW, TC_BLACK); + if (oid == v->cur_real_order_index) DrawString(left, right, y, STR_JUST_RIGHT_ARROW, TC_BLACK, SA_LEFT, false, FS_SMALL); if (order->IsType(OT_GOTO_STATION)) { SetDParam(0, order->GetDestination());