mirror of https://github.com/OpenTTD/OpenTTD
(svn r22394) [1.1] -Backport from trunk:
- Change: Show one digit of the fractional train length in the depot (r22336, r22305, r22304, r22303) - Fix: Check the availability year of all houses, not just the NewGRF houses, when making sure that at least one is available onwards from year 0 [FS#4581] (r22389, r22300, r22299) - Fix: When a game uses a lot of NewGRFs the buffer for storing that information in the PNG is too small (r22388)release/1.1
parent
e43d961737
commit
2b2cabfce1
|
@ -285,9 +285,10 @@ struct DepotWindow : Window {
|
|||
DrawTrainImage(u, image_left + (rtl ? 0 : x_space), image_right - (rtl ? x_space : 0), sprite_y - 1,
|
||||
this->sel, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
|
||||
|
||||
/* Length of consist in tiles (rounded up) */
|
||||
SetDParam(0, CeilDiv(u->gcache.cached_total_length, TILE_SIZE));
|
||||
DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT); // Draw the counter
|
||||
/* Length of consist in tiles with 1 fractional digit (rounded up) */
|
||||
SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
|
||||
SetDParam(1, 1);
|
||||
DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -598,8 +599,9 @@ struct DepotWindow : Window {
|
|||
uint min_height = 0;
|
||||
|
||||
if (this->type == VEH_TRAIN) {
|
||||
SetDParam(0, 100);
|
||||
this->count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
|
||||
SetDParam(0, 1000);
|
||||
SetDParam(1, 1);
|
||||
this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
|
||||
} else {
|
||||
this->count_width = 0;
|
||||
}
|
||||
|
|
|
@ -4242,6 +4242,7 @@ STR_TINY_BLACK_COMA :{TINYFONT}{BLAC
|
|||
STR_TINY_COMMA :{TINYFONT}{COMMA}
|
||||
STR_BLUE_COMMA :{BLUE}{COMMA}
|
||||
STR_RED_COMMA :{RED}{COMMA}
|
||||
STR_TINY_BLACK_DECIMAL :{TINYFONT}{BLACK}{DECIMAL}
|
||||
STR_COMPANY_MONEY :{WHITE}{CURRENCY}
|
||||
STR_BLACK_DATE_LONG :{BLACK}{DATE_LONG}
|
||||
STR_BLACK_CROSS :{BLACK}{CROSS}
|
||||
|
|
|
@ -7606,6 +7606,33 @@ static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseS
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure there is at least one house available in the year 0 for the given
|
||||
* climate / housezone combination.
|
||||
* @param bitmask The climate and housezone to check for. Exactly one climate
|
||||
* bit and one housezone bit should be set.
|
||||
*/
|
||||
static void EnsureEarlyHouse(HouseZones bitmask)
|
||||
{
|
||||
Year min_year = MAX_YEAR;
|
||||
|
||||
for (int i = 0; i < HOUSE_MAX; i++) {
|
||||
HouseSpec *hs = HouseSpec::Get(i);
|
||||
if (hs == NULL || !hs->enabled) continue;
|
||||
if ((hs->building_availability & bitmask) != bitmask) continue;
|
||||
if (hs->min_year < min_year) min_year = hs->min_year;
|
||||
}
|
||||
|
||||
if (min_year == 0) return;
|
||||
|
||||
for (int i = 0; i < HOUSE_MAX; i++) {
|
||||
HouseSpec *hs = HouseSpec::Get(i);
|
||||
if (hs == NULL || !hs->enabled) continue;
|
||||
if ((hs->building_availability & bitmask) != bitmask) continue;
|
||||
if (hs->min_year == min_year) hs->min_year = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all new houses to the house array. House properties can be set at any
|
||||
* time in the GRF file, so we can only add a house spec to the house array
|
||||
|
@ -7623,8 +7650,6 @@ static void FinaliseHouseArray()
|
|||
* On the other hand, why 1930? Just 'fix' the houses with the lowest
|
||||
* minimum introduction date to 0.
|
||||
*/
|
||||
Year min_year = MAX_YEAR;
|
||||
|
||||
const GRFFile * const *end = _grf_files.End();
|
||||
for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
|
||||
HouseSpec **&housespec = (*file)->housespec;
|
||||
|
@ -7642,7 +7667,6 @@ static void FinaliseHouseArray()
|
|||
if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
|
||||
|
||||
_house_mngr.SetEntitySpec(hs);
|
||||
if (hs->min_year < min_year) min_year = hs->min_year;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7666,12 +7690,19 @@ static void FinaliseHouseArray()
|
|||
}
|
||||
}
|
||||
|
||||
if (min_year != 0) {
|
||||
for (int i = 0; i < HOUSE_MAX; i++) {
|
||||
HouseSpec *hs = HouseSpec::Get(i);
|
||||
HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
|
||||
EnsureEarlyHouse(HZ_ZON1 | climate_mask);
|
||||
EnsureEarlyHouse(HZ_ZON2 | climate_mask);
|
||||
EnsureEarlyHouse(HZ_ZON3 | climate_mask);
|
||||
EnsureEarlyHouse(HZ_ZON4 | climate_mask);
|
||||
EnsureEarlyHouse(HZ_ZON5 | climate_mask);
|
||||
|
||||
if (hs->enabled && hs->min_year == min_year) hs->min_year = 0;
|
||||
}
|
||||
if (_settings_game.game_creation.landscape == LT_ARCTIC) {
|
||||
EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
|
||||
EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
|
||||
EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
|
||||
EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
|
||||
EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user
|
|||
text[0].text_length = strlen(_openttd_revision);
|
||||
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
|
||||
char buf[2048];
|
||||
char buf[8192];
|
||||
char *p = buf;
|
||||
p += seprintf(p, lastof(buf), "Graphics set: %s (%u)\n", BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet()->version);
|
||||
p = strecpy(p, "NewGRFs:\n", lastof(buf));
|
||||
|
|
|
@ -231,9 +231,23 @@ void InjectDParam(uint amount)
|
|||
memmove(_decode_parameters + amount, _decode_parameters, sizeof(_decode_parameters) - amount * sizeof(uint64));
|
||||
}
|
||||
|
||||
static char *FormatNumber(char *buff, int64 number, const char *last, const char *separator, int zerofill_from = 19)
|
||||
/**
|
||||
* Format a number into a string.
|
||||
* @param buff the buffer to write to
|
||||
* @param number the number to write down
|
||||
* @param last the last element in the buffer
|
||||
* @param separator the thousands-separator to use
|
||||
* @param zerofill minimum number of digits to print for the integer part. The number will be filled with zeros at the front if necessary.
|
||||
* @param fractional_digits number of fractional digits to display after a decimal separator. The decimal separator is inserted
|
||||
* in front of the \a fractional_digits last digit of \a number.
|
||||
* @return till where we wrote
|
||||
*/
|
||||
static char *FormatNumber(char *buff, int64 number, const char *last, const char *separator, int zerofill = 1, int fractional_digits = 0)
|
||||
{
|
||||
static const int max_digits = 20;
|
||||
uint64 divisor = 10000000000000000000ULL;
|
||||
zerofill += fractional_digits;
|
||||
int thousands_offset = (max_digits - fractional_digits - 1) % 3;
|
||||
|
||||
if (number < 0) {
|
||||
buff += seprintf(buff, last, "-");
|
||||
|
@ -242,15 +256,21 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char
|
|||
|
||||
uint64 num = number;
|
||||
uint64 tot = 0;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
for (int i = 0; i < max_digits; i++) {
|
||||
if (i == max_digits - fractional_digits) {
|
||||
const char *decimal_separator = _settings_game.locale.digit_decimal_separator;
|
||||
if (decimal_separator == NULL) decimal_separator = _langpack->digit_decimal_separator;
|
||||
buff += seprintf(buff, last, "%s", decimal_separator);
|
||||
}
|
||||
|
||||
uint64 quot = 0;
|
||||
if (num >= divisor) {
|
||||
quot = num / divisor;
|
||||
num = num % divisor;
|
||||
}
|
||||
if (tot |= quot || i >= zerofill_from) {
|
||||
if (tot |= quot || i >= max_digits - zerofill) {
|
||||
buff += seprintf(buff, last, "%i", (int)quot);
|
||||
if ((i % 3) == 1 && i != 19) buff = strecpy(buff, separator, last);
|
||||
if ((i % 3) == thousands_offset && i < max_digits - 1 - fractional_digits) buff = strecpy(buff, separator, last);
|
||||
}
|
||||
|
||||
divisor /= 10;
|
||||
|
@ -261,11 +281,11 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char
|
|||
return buff;
|
||||
}
|
||||
|
||||
static char *FormatCommaNumber(char *buff, int64 number, const char *last)
|
||||
static char *FormatCommaNumber(char *buff, int64 number, const char *last, int fractional_digits = 0)
|
||||
{
|
||||
const char *separator = _settings_game.locale.digit_group_separator;
|
||||
if (separator == NULL) separator = _langpack->digit_group_separator;
|
||||
return FormatNumber(buff, number, last, separator);
|
||||
return FormatNumber(buff, number, last, separator, 1, fractional_digits);
|
||||
}
|
||||
|
||||
static char *FormatNoCommaNumber(char *buff, int64 number, const char *last)
|
||||
|
@ -275,7 +295,7 @@ static char *FormatNoCommaNumber(char *buff, int64 number, const char *last)
|
|||
|
||||
static char *FormatZerofillNumber(char *buff, int64 number, int64 count, const char *last)
|
||||
{
|
||||
return FormatNumber(buff, number, last, "", 20 - count);
|
||||
return FormatNumber(buff, number, last, "", count);
|
||||
}
|
||||
|
||||
static char *FormatHexNumber(char *buff, uint64 number, const char *last)
|
||||
|
@ -989,6 +1009,13 @@ static char *FormatString(char *buff, const char *str_arg, int64 *argv, const in
|
|||
buff = FormatCommaNumber(buff, GetInt64(&argv, argve, &argt, SCC_COMMA), last);
|
||||
break;
|
||||
|
||||
case SCC_DECIMAL: {// {DECIMAL}
|
||||
int64 number = GetInt64(&argv, argve, &argt, SCC_DECIMAL);
|
||||
int digits = GetInt32(&argv, argve, &argt, SCC_DECIMAL);
|
||||
buff = FormatCommaNumber(buff, number, last, digits);
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_ARG_INDEX: { // Move argument pointer
|
||||
byte offset = (byte)*str++;
|
||||
argv = argv_orig + offset;
|
||||
|
|
|
@ -72,6 +72,7 @@ enum StringControlCode {
|
|||
|
||||
SCC_STRING,
|
||||
SCC_COMMA,
|
||||
SCC_DECIMAL,
|
||||
SCC_NUM,
|
||||
SCC_ZEROFILL_NUM,
|
||||
SCC_HEX,
|
||||
|
|
|
@ -92,6 +92,7 @@ static const CmdStruct _cmd_structs[] = {
|
|||
|
||||
/* Numbers */
|
||||
{"COMMA", EmitSingleChar, SCC_COMMA, 1, C_NONE}, // Number with comma
|
||||
{"DECIMAL", EmitSingleChar, SCC_DECIMAL, 2, C_NONE}, // Number with comma and fractional part. Second parameter is number of fractional digits, first parameter is number times 10**(second parameter).
|
||||
{"NUM", EmitSingleChar, SCC_NUM, 1, C_NONE}, // Signed number
|
||||
{"ZEROFILL_NUM", EmitSingleChar, SCC_ZEROFILL_NUM, 2, C_NONE}, // Unsigned number with zero fill, e.g. "02". First parameter is number, second minimum length
|
||||
{"BYTES", EmitSingleChar, SCC_BYTES, 1, C_NONE}, // Unsigned number with "bytes", i.e. "1.02 MiB or 123 KiB"
|
||||
|
|
Loading…
Reference in New Issue