diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 6415493b37..5d424676bb 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -890,7 +890,7 @@ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList * int count_width = 0; if (show_count) { replace_icon = GetSpriteSize(SPR_GROUP_REPLACE_ACTIVE); - SetDParam(0, 999); + SetDParamMaxDigits(0, 3); count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width; } diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 18901c5dab..6b37079bd3 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -259,7 +259,7 @@ struct CheatWindow : Window { /* Draw coloured flag for change company cheat */ case STR_CHEAT_CHANGE_COMPANY: - SetDParam(0, 15); + SetDParamMaxValue(0, MAX_COMPANIES); width = max(width, GetStringBoundingBox(ce->str).width + 10 + 10); break; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index ae6f394e97..c6ddd6bd0b 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -319,7 +319,7 @@ struct CompanyFinancesWindow : Window { case WID_CF_BALANCE_VALUE: case WID_CF_LOAN_VALUE: case WID_CF_TOTAL_VALUE: - SetDParam(0, CompanyFinancesWindow::max_money); + SetDParamMaxValue(0, CompanyFinancesWindow::max_money); size->width = max(GetStringBoundingBox(STR_FINANCES_NEGATIVE_INCOME).width, GetStringBoundingBox(STR_FINANCES_POSITIVE_INCOME).width) + padding.width; break; @@ -1691,12 +1691,12 @@ struct CompanyInfrastructureWindow : Window max_val = max(max_val, c->infrastructure.airport); max_cost = max(max_cost, AirportMaintenanceCost(c->index)); - SetDParam(0, max_val); - SetDParam(1, max_cost * 12); // Convert to per year + SetDParamMaxValue(0, max_val); + SetDParamMaxValue(1, max_cost * 12); // Convert to per year size->width = max(size->width, GetStringBoundingBox(_settings_game.economy.infrastructure_maintenance ? STR_COMPANY_INFRASTRUCTURE_VIEW_COST : STR_WHITE_COMMA).width + 20); // Reserve some wiggle room. if (_settings_game.economy.infrastructure_maintenance) { - SetDParam(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year + SetDParamMaxValue(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year this->total_width = GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL).width + 20; size->width = max(size->width, this->total_width); } @@ -2095,14 +2095,14 @@ struct CompanyWindow : Window break; case WID_C_DESC_VEHICLE_COUNTS: - SetDParam(0, 5000); // Maximum number of vehicles + SetDParamMaxValue(0, 5000); // Maximum number of vehicles for (uint i = 0; i < lengthof(_company_view_vehicle_count_strings); i++) { size->width = max(size->width, GetStringBoundingBox(_company_view_vehicle_count_strings[i]).width); } break; case WID_C_DESC_INFRASTRUCTURE_COUNTS: - SetDParam(0, UINT_MAX); + SetDParamMaxValue(0, UINT_MAX); size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_INFRASTRUCTURE_RAIL).width); size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_INFRASTRUCTURE_ROAD).width); size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_INFRASTRUCTURE_WATER).width); @@ -2115,7 +2115,7 @@ struct CompanyWindow : Window const Company *c2; FOR_ALL_COMPANIES(c2) { - SetDParam(0, 25); + SetDParamMaxValue(0, 75); SetDParam(1, c2->index); size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_SHARES_OWNED_BY).width); diff --git a/src/date_gui.cpp b/src/date_gui.cpp index 3162a4ef99..b2421556ce 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -117,10 +117,8 @@ struct SetDateWindow : Window { break; case WID_SD_YEAR: - for (Year i = this->min_year; i <= this->max_year; i++) { - SetDParam(0, i); - d = maxdim(d, GetStringBoundingBox(STR_JUST_INT)); - } + SetDParamMaxValue(0, this->max_year); + d = maxdim(d, GetStringBoundingBox(STR_JUST_INT)); break; } diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 758c5f5af5..25d36b690c 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -579,7 +579,7 @@ struct DepotWindow : Window { uint min_height = 0; if (this->type == VEH_TRAIN) { - SetDParam(0, 1000); + SetDParamMaxValue(0, 1000); SetDParam(1, 1); this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; } else { diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index ba1a95df3d..1666a48034 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -449,12 +449,12 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_MAPSIZE_X_PULLDOWN: case WID_GL_MAPSIZE_Y_PULLDOWN: - SetDParam(0, MAX_MAP_SIZE); + SetDParamMaxValue(0, MAX_MAP_SIZE); *size = GetStringBoundingBox(STR_JUST_INT); break; case WID_GL_SNOW_LEVEL_TEXT: - SetDParam(0, MAX_TILE_HEIGHT); + SetDParamMaxValue(0, MAX_TILE_HEIGHT); *size = GetStringBoundingBox(STR_JUST_INT); break; @@ -466,7 +466,7 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_TOWN_PULLDOWN: strs = _num_towns; - SetDParam(0, CUSTOM_TOWN_MAX_NUMBER); + SetDParamMaxValue(0, CUSTOM_TOWN_MAX_NUMBER); *size = GetStringBoundingBox(STR_NUM_CUSTOM_NUMBER); break; @@ -476,7 +476,7 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_TERRAIN_PULLDOWN: strs = _elevations; break; case WID_GL_WATER_PULLDOWN: strs = _sea_lakes; - SetDParam(0, CUSTOM_SEA_LEVEL_MAX_PERCENTAGE); + SetDParamMaxValue(0, CUSTOM_SEA_LEVEL_MAX_PERCENTAGE); *size = GetStringBoundingBox(STR_SEA_LEVEL_CUSTOM_PERCENTAGE); break; @@ -923,11 +923,11 @@ struct CreateScenarioWindow : public Window case WID_CS_MAPSIZE_X_PULLDOWN: case WID_CS_MAPSIZE_Y_PULLDOWN: - SetDParam(0, MAX_MAP_SIZE); + SetDParamMaxValue(0, MAX_MAP_SIZE); break; case WID_CS_FLAT_LAND_HEIGHT_TEXT: - SetDParam(0, MAX_TILE_HEIGHT); + SetDParamMaxValue(0, MAX_TILE_HEIGHT); break; default: @@ -1194,7 +1194,7 @@ struct GenerateProgressWindow : public Window { { switch (widget) { case WID_GP_PROGRESS_BAR: { - SetDParam(0, 100); + SetDParamMaxValue(0, 100); *size = GetStringBoundingBox(STR_GENERATION_PROGRESS); /* We need some spacing for the 'border' */ size->height += 8; diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 0d87bba00c..82d862d33f 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -504,7 +504,7 @@ public: } } else { /* Draw the label under the data point rather than on the grid line. */ - SetDParam(0, this->x_values_start + this->num_on_x_axis * this->x_values_increment); + SetDParamMaxValue(0, this->x_values_start + this->num_on_x_axis * this->x_values_increment); x_label_width = GetStringBoundingBox(STR_GRAPH_Y_LABEL_NUMBER).width; } @@ -1322,10 +1322,10 @@ struct PerformanceRatingDetailWindow : Window { for (uint i = SCORE_BEGIN; i < SCORE_END; i++) { score_info_width = max(score_info_width, GetStringBoundingBox(STR_PERFORMANCE_DETAIL_VEHICLES + i).width); } - SetDParam(0, 1000); + SetDParamMaxValue(0, 1000); score_info_width += GetStringBoundingBox(STR_BLACK_COMMA).width + WD_FRAMERECT_LEFT; - SetDParam(0, 100); + SetDParamMaxValue(0, 100); this->bar_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_PERCENT).width + 20; // Wide bars! /* At this number we are roughly at the max; it can become wider, diff --git a/src/group_gui.cpp b/src/group_gui.cpp index bbb6e9d0eb..3996ddc187 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -182,7 +182,7 @@ private: } this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_PROFIT].height); - SetDParam(0, GroupStatistics::Get(this->vli.company, ALL_GROUP, this->vli.vtype).num_vehicle > 900 ? 9999 : 999); + SetDParamMaxValue(0, GroupStatistics::Get(this->vli.company, ALL_GROUP, this->vli.vtype).num_vehicle, 3); this->column_size[VGC_NUMBER] = GetStringBoundingBox(STR_TINY_COMMA); this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_NUMBER].height); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 55dc817614..c0a73d8080 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -526,24 +526,24 @@ public: case WID_NG_CLIENTS: size->width += 2 * WD_SORTBUTTON_ARROW_WIDTH; // Make space for the arrow - SetDParam(0, MAX_CLIENTS); - SetDParam(1, MAX_CLIENTS); - SetDParam(2, MAX_COMPANIES); - SetDParam(3, MAX_COMPANIES); + SetDParamMaxValue(0, MAX_CLIENTS); + SetDParamMaxValue(1, MAX_CLIENTS); + SetDParamMaxValue(2, MAX_COMPANIES); + SetDParamMaxValue(3, MAX_COMPANIES); *size = maxdim(*size, GetStringBoundingBox(STR_NETWORK_SERVER_LIST_GENERAL_ONLINE)); break; case WID_NG_MAPSIZE: size->width += 2 * WD_SORTBUTTON_ARROW_WIDTH; // Make space for the arrow - SetDParam(0, MAX_MAP_SIZE); - SetDParam(1, MAX_MAP_SIZE); + SetDParamMaxValue(0, MAX_MAP_SIZE); + SetDParamMaxValue(1, MAX_MAP_SIZE); *size = maxdim(*size, GetStringBoundingBox(STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT)); break; case WID_NG_DATE: case WID_NG_YEARS: size->width += 2 * WD_SORTBUTTON_ARROW_WIDTH; // Make space for the arrow - SetDParam(0, 99999); + SetDParamMaxValue(0, 5); *size = maxdim(*size, GetStringBoundingBox(STR_JUST_INT)); break; @@ -2071,12 +2071,12 @@ struct NetworkJoinStatusWindow : Window { } /* For the number of waiting (other) players */ - SetDParam(0, MAX_CLIENTS); + SetDParamMaxValue(0, MAX_CLIENTS); width = max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_WAITING).width); /* Account for downloading ~ 10 MiB */ - SetDParam(0, 10000000); - SetDParam(1, 10000000); + SetDParamMaxDigits(0, 8); + SetDParamMaxDigits(1, 8); width = max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_1).width); width = max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_2).width); diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index bcdaa8db86..e052cc19c5 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -197,7 +197,7 @@ struct NewGRFParametersWindow : public Window { } case WID_NP_NUMPAR: { - SetDParam(0, 999); + SetDParamMaxValue(0, lengthof(this->grf_config->param)); Dimension d = GetStringBoundingBox(this->GetWidget(widget)->widget_data); d.width += padding.width; d.height += padding.height; @@ -1965,7 +1965,7 @@ struct ScanProgressWindow : public Window { { switch (widget) { case WID_SP_PROGRESS_BAR: { - SetDParam(0, 100); + SetDParamMaxValue(0, 100); *size = GetStringBoundingBox(STR_GENERATION_PROGRESS); /* We need some spacing for the 'border' */ size->height += 8; @@ -1974,8 +1974,8 @@ struct ScanProgressWindow : public Window { } case WID_SP_PROGRESS_TEXT: - SetDParam(0, 9999); - SetDParam(1, 9999); + SetDParamMaxDigits(0, 4); + SetDParamMaxDigits(1, 4); /* We really don't know the width. We could determine it by scanning the NewGRFs, * but this is the status window for scanning them... */ size->width = max(400U, GetStringBoundingBox(STR_NEWGRF_SCAN_STATUS).width); diff --git a/src/order_gui.cpp b/src/order_gui.cpp index f50ef73ed1..85bd196ef4 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1097,7 +1097,7 @@ public: if (widget != WID_O_ORDER_LIST) return; bool rtl = _current_text_dir == TD_RTL; - SetDParam(0, 99); + SetDParamMaxValue(0, this->vehicle->GetNumOrders(), 2); int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3; int middle = rtl ? r.right - WD_FRAMETEXT_RIGHT - index_column_width : r.left + WD_FRAMETEXT_LEFT + index_column_width; diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 0f2d316905..120906ae9e 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -274,7 +274,7 @@ struct SignListWindow : Window, SignList { } case WID_SIL_CAPTION: - SetDParam(0, max(1000, Sign::GetPoolSize())); + SetDParamMaxValue(0, Sign::GetPoolSize(), 3); *size = GetStringBoundingBox(STR_SIGN_LIST_CAPTION); size->height += padding.height; size->width += padding.width; diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 4a014d2613..f8d39ceaf4 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -104,7 +104,7 @@ struct StatusBarWindow : Window { Dimension d; switch (widget) { case WID_S_LEFT: - SetDParam(0, MAX_YEAR * DAYS_IN_YEAR); + SetDParamMaxValue(0, MAX_YEAR * DAYS_IN_YEAR); d = GetStringBoundingBox(STR_WHITE_DATE_LONG); break; diff --git a/src/strings.cpp b/src/strings.cpp index 12f41e1588..a8a7cc62b6 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -90,6 +90,38 @@ void StringParameters::ShiftParameters(uint amount) MemMoveT(this->data + amount, this->data, this->num_param - amount); } +/** + * Set DParam n to some number that is suitable for string size computations. + * @param n Index of the string parameter. + * @param max_value The biggest value which shall be displayed. + * For the result only the number of digits of \a max_value matter. + * @param min_count Minimum number of digits indepentent of \a max. + */ +void SetDParamMaxValue(uint n, uint64 max_value, uint min_count) +{ + uint num_digits = 1; + while (max_value >= 10) { + num_digits++; + max_value /= 10; + } + SetDParamMaxDigits(n, max(min_count, num_digits)); +} + +/** + * Set DParam n to some number that is suitable for string size computations. + * @param n Index of the string parameter. + * @param count Number of digits which shall be displayable. + */ +void SetDParamMaxDigits(uint n, uint count) +{ + static const uint biggest_digit = 8; ///< Digit with the biggest string width. + uint64 val = biggest_digit; + for (; count > 1; count--) { + val = 10 * val + biggest_digit; + } + SetDParam(n, val); +} + /** * Copy \a num string parameters from array \a src into the global string parameter array. * @param offs Index in the global array to copy the first string parameter to. diff --git a/src/strings_func.h b/src/strings_func.h index 395a80e1a1..f977b3b3cd 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -155,6 +155,9 @@ static inline void SetDParam(uint n, uint64 v) _global_string_params.SetParam(n, v); } +void SetDParamMaxValue(uint n, uint64 max_value, uint min_count = 0); +void SetDParamMaxDigits(uint n, uint count); + void SetDParamStr(uint n, const char *str); void CopyInDParam(int offs, const uint64 *src, int num); diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 272682eb17..6533e351d5 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -200,7 +200,7 @@ struct TimetableWindow : Window { { switch (widget) { case WID_VT_ARRIVAL_DEPARTURE_PANEL: - SetDParam(0, MAX_YEAR * DAYS_IN_YEAR); + SetDParamMaxValue(0, MAX_YEAR * DAYS_IN_YEAR); this->deparr_time_width = GetStringBoundingBox(STR_JUST_DATE_TINY).width; this->deparr_abbr_width = max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL_ABBREVIATION).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE_ABBREVIATION).width); size->width = WD_FRAMERECT_LEFT + this->deparr_abbr_width + 10 + this->deparr_time_width + WD_FRAMERECT_RIGHT; @@ -368,7 +368,7 @@ struct TimetableWindow : Window { bool final_order = false; bool rtl = _current_text_dir == TD_RTL; - SetDParam(0, 99); + SetDParamMaxValue(0, v->GetNumOrders(), 2); int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3; int middle = rtl ? r.right - WD_FRAMERECT_RIGHT - index_column_width : r.left + WD_FRAMERECT_LEFT + index_column_width; diff --git a/src/town_gui.cpp b/src/town_gui.cpp index ad9ee06056..490bca5ed9 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -780,7 +780,7 @@ public: assert(t != NULL); SetDParam(0, t->index); - SetDParam(1, 10000000); // 10^7 + SetDParamMaxDigits(1, 8); d = maxdim(d, GetStringBoundingBox(STR_TOWN_DIRECTORY_TOWN)); } Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD); @@ -794,7 +794,7 @@ public: break; } case WID_TD_WORLD_POPULATION: { - SetDParam(0, 1000000000); // 10^9 + SetDParamMaxDigits(0, 10); Dimension d = GetStringBoundingBox(STR_TOWN_POPULATION); d.width += padding.width; d.height += padding.height; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index d939375866..f64a3cc473 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1805,7 +1805,7 @@ struct VehicleDetailsWindow : Window { Dimension dim = { 0, 0 }; size->height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM; - for (uint i = 0; i < 4; i++) SetDParam(i, INT16_MAX); + for (uint i = 0; i < 4; i++) SetDParamMaxValue(i, INT16_MAX); static const StringID info_strings[] = { STR_VEHICLE_INFO_MAX_SPEED, STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED, @@ -1849,8 +1849,8 @@ struct VehicleDetailsWindow : Window { break; case WID_VD_SERVICING_INTERVAL: - SetDParam(0, 9999); // Roughly the maximum interval - SetDParam(1, MAX_YEAR * DAYS_IN_YEAR); // Roughly the maximum year + SetDParamMaxValue(0, MAX_SERVINT_DAYS); // Roughly the maximum interval + SetDParamMaxValue(1, MAX_YEAR * DAYS_IN_YEAR); // Roughly the maximum year size->width = max(GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT).width, GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; size->height = WD_FRAMERECT_TOP + FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM; break;