Update to 12.0-beta1

This commit is contained in:
dP
2021-08-15 14:57:29 +03:00
parent ac7d3eba75
commit 9df4f2c4fc
666 changed files with 61302 additions and 20466 deletions

View File

@@ -70,12 +70,12 @@ void StringParameters::ClearTypeInformation()
int64 StringParameters::GetInt64(WChar type)
{
if (this->offset >= this->num_param) {
DEBUG(misc, 0, "Trying to read invalid string parameter");
Debug(misc, 0, "Trying to read invalid string parameter");
return 0;
}
if (this->type != nullptr) {
if (this->type[this->offset] != 0 && this->type[this->offset] != type) {
DEBUG(misc, 0, "Trying to read string parameter with wrong type");
Debug(misc, 0, "Trying to read string parameter with wrong type");
return 0;
}
this->type[this->offset] = type;
@@ -83,16 +83,6 @@ int64 StringParameters::GetInt64(WChar type)
return this->data[this->offset++];
}
/**
* Shift all data in the data array by the given amount to make
* room for some extra parameters.
*/
void StringParameters::ShiftParameters(uint amount)
{
assert(amount <= this->num_param);
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.
@@ -185,8 +175,16 @@ struct LanguagePack : public LanguagePackHeader {
char data[]; // list of strings
};
struct LanguagePackDeleter {
void operator()(LanguagePack *langpack)
{
/* LanguagePack is in fact reinterpreted char[], we need to reinterpret it back to free it properly. */
delete[] reinterpret_cast<char*>(langpack);
}
};
struct LoadedLanguagePack {
std::unique_ptr<LanguagePack> langpack;
std::unique_ptr<LanguagePack, LanguagePackDeleter> langpack;
std::vector<char *> offsets;
@@ -277,6 +275,18 @@ char *GetString(char *buffr, StringID string, const char *last)
return GetStringWithArgs(buffr, string, &_global_string_params, last);
}
/**
* Resolve the given StringID into a std::string with all the associated
* DParam lookups and formatting.
* @param string The unique identifier of the translatable string.
* @return The std::string of the translated string.
*/
std::string GetString(StringID string)
{
char buffer[DRAW_STRING_BUFFER];
GetString(buffer, string, lastof(buffer));
return buffer;
}
/**
* This function is used to "bind" a C string to a OpenTTD dparam slot.
@@ -289,12 +299,14 @@ void SetDParamStr(uint n, const char *str)
}
/**
* Shift the string parameters in the global string parameter array by \a amount positions, making room at the beginning.
* @param amount Number of positions to shift.
* This function is used to "bind" the C string of a std::string to a OpenTTD dparam slot.
* The caller has to ensure that the std::string reference remains valid while the string is shown.
* @param n slot of the string
* @param str string to bind
*/
void InjectDParam(uint amount)
void SetDParamStr(uint n, const std::string &str)
{
_global_string_params.ShiftParameters(amount);
SetDParamStr(n, str.c_str());
}
/**
@@ -324,8 +336,8 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char
uint64 tot = 0;
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 == nullptr) decimal_separator = _langpack.langpack->digit_decimal_separator;
const char *decimal_separator = _settings_game.locale.digit_decimal_separator.c_str();
if (StrEmpty(decimal_separator)) decimal_separator = _langpack.langpack->digit_decimal_separator;
buff += seprintf(buff, last, "%s", decimal_separator);
}
@@ -349,8 +361,8 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char
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 == nullptr) separator = _langpack.langpack->digit_group_separator;
const char *separator = _settings_game.locale.digit_group_separator.c_str();
if (StrEmpty(separator)) separator = _langpack.langpack->digit_group_separator;
return FormatNumber(buff, number, last, separator, 1, fractional_digits);
}
@@ -388,8 +400,8 @@ static char *FormatBytes(char *buff, int64 number, const char *last)
id++;
}
const char *decimal_separator = _settings_game.locale.digit_decimal_separator;
if (decimal_separator == nullptr) decimal_separator = _langpack.langpack->digit_decimal_separator;
const char *decimal_separator = _settings_game.locale.digit_decimal_separator.c_str();
if (StrEmpty(decimal_separator)) decimal_separator = _langpack.langpack->digit_decimal_separator;
if (number < 1024) {
id = 0;
@@ -467,7 +479,7 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n
/* Add prefix part, following symbol_pos specification.
* Here, it can can be either 0 (prefix) or 2 (both prefix and suffix).
* The only remaining value is 1 (suffix), so everything that is not 1 */
if (spec->symbol_pos != 1) buff = strecpy(buff, spec->prefix, last);
if (spec->symbol_pos != 1) buff = strecpy(buff, spec->prefix.c_str(), last);
/* for huge numbers, compact the number into k or M */
if (compact) {
@@ -482,16 +494,16 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n
}
}
const char *separator = _settings_game.locale.digit_group_separator_currency;
if (separator == nullptr && !StrEmpty(_currency->separator)) separator = _currency->separator;
if (separator == nullptr) separator = _langpack.langpack->digit_group_separator_currency;
const char *separator = _settings_game.locale.digit_group_separator_currency.c_str();
if (StrEmpty(separator)) separator = _currency->separator.c_str();
if (StrEmpty(separator)) separator = _langpack.langpack->digit_group_separator_currency;
buff = FormatNumber(buff, number, last, separator);
buff = strecpy(buff, multiplier, last);
/* Add suffix part, following symbol_pos specification.
* Here, it can can be either 1 (suffix) or 2 (both prefix and suffix).
* The only remaining value is 1 (prefix), so everything that is not 0 */
if (spec->symbol_pos != 0) buff = strecpy(buff, spec->suffix, last);
if (spec->symbol_pos != 0) buff = strecpy(buff, spec->suffix.c_str(), last);
if (negative) {
if (buff + Utf8CharLen(SCC_POP_COLOUR) > last) return buff;
@@ -526,7 +538,7 @@ static int DeterminePluralForm(int64 count, int plural_form)
/* Only one form.
* Used in:
* Hungarian, Japanese, Korean, Turkish */
* Hungarian, Japanese, Turkish */
case 1:
return 0;
@@ -817,7 +829,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg
const char *&str = str_stack.top();
if (SCC_NEWGRF_FIRST <= b && b <= SCC_NEWGRF_LAST) {
/* We need to pass some stuff as it might be modified; oh boy. */
/* We need to pass some stuff as it might be modified. */
//todo: should argve be passed here too?
b = RemapNewGRFStringControlCode(b, buf_start, &buff, &str, (int64 *)args->GetDataPointer(), args->GetDataLeft(), dry_run);
if (b == 0) continue;
@@ -1163,8 +1175,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg
CargoTypes cmask = args->GetInt64(SCC_CARGO_LIST);
bool first = true;
const CargoSpec *cs;
FOR_ALL_SORTED_CARGOSPECS(cs) {
for (const auto &cs : _sorted_cargo_specs) {
if (!HasBit(cmask, cs->Index())) continue;
if (buff >= last - 2) break; // ',' and ' '
@@ -1687,8 +1698,6 @@ static char *GetSpecialNameString(char *buff, int ind, StringParameters *args, c
NOT_REACHED();
}
extern void SortNetworkLanguages();
/**
* Check whether the header is a valid header for OpenTTD.
* @return true iff the header is deemed valid.
@@ -1710,6 +1719,15 @@ bool LanguagePackHeader::IsValid() const
StrValid(this->digit_decimal_separator, lastof(this->digit_decimal_separator));
}
/**
* Check whether a translation is sufficiently finished to offer it to the public.
*/
bool LanguagePackHeader::IsReasonablyFinished() const
{
/* "Less than 25% missing" is "sufficiently finished". */
return 4 * this->missing < LANGUAGE_TOTAL_STRINGS;
}
/**
* Read a particular language.
* @param lang The metadata about the language.
@@ -1719,7 +1737,7 @@ bool ReadLanguagePack(const LanguageMetadata *lang)
{
/* Current language pack */
size_t len = 0;
std::unique_ptr<LanguagePack> lang_pack(reinterpret_cast<LanguagePack *>(ReadFileToMem(lang->file, len, 1U << 20).release()));
std::unique_ptr<LanguagePack, LanguagePackDeleter> lang_pack(reinterpret_cast<LanguagePack *>(ReadFileToMem(lang->file, len, 1U << 20).release()));
if (!lang_pack) return false;
/* End of read data (+ terminating zero added in ReadFileToMem()) */
@@ -1805,7 +1823,6 @@ bool ReadLanguagePack(const LanguageMetadata *lang)
InitializeSortedCargoSpecs();
SortIndustryTypes();
BuildIndustriesLegend();
SortNetworkLanguages();
BuildContentTypeStringList();
InvalidateWindowClassesData(WC_BUILD_VEHICLE); // Build vehicle window.
InvalidateWindowClassesData(WC_TRAINS_LIST); // Train group window.
@@ -1833,18 +1850,18 @@ const char *GetCurrentLocale(const char *param)
{
const char *env;
env = getenv("LANGUAGE");
env = std::getenv("LANGUAGE");
if (env != nullptr) return env;
env = getenv("LC_ALL");
env = std::getenv("LC_ALL");
if (env != nullptr) return env;
if (param != nullptr) {
env = getenv(param);
env = std::getenv(param);
if (env != nullptr) return env;
}
return getenv("LANG");
return std::getenv("LANG");
}
#else
const char *GetCurrentLocale(const char *param);
@@ -1908,20 +1925,20 @@ static void GetLanguageList(const char *path)
if (dir != nullptr) {
struct dirent *dirent;
while ((dirent = readdir(dir)) != nullptr) {
const char *d_name = FS2OTTD(dirent->d_name);
const char *extension = strrchr(d_name, '.');
std::string d_name = FS2OTTD(dirent->d_name);
const char *extension = strrchr(d_name.c_str(), '.');
/* Not a language file */
if (extension == nullptr || strcmp(extension, ".lng") != 0) continue;
LanguageMetadata lmd;
seprintf(lmd.file, lastof(lmd.file), "%s%s", path, d_name);
seprintf(lmd.file, lastof(lmd.file), "%s%s", path, d_name.c_str());
/* Check whether the file is of the correct version */
if (!GetLanguageFileHeader(lmd.file, &lmd)) {
DEBUG(misc, 3, "%s is not a valid language file", lmd.file);
Debug(misc, 3, "{} is not a valid language file", lmd.file);
} else if (GetLanguage(lmd.newgrflangid) != nullptr) {
DEBUG(misc, 3, "%s's language ID is already known", lmd.file);
Debug(misc, 3, "{}'s language ID is already known", lmd.file);
} else {
_languages.push_back(lmd);
}
@@ -1936,9 +1953,7 @@ static void GetLanguageList(const char *path)
*/
void InitializeLanguagePacks()
{
Searchpath sp;
FOR_ALL_SEARCHPATHS(sp) {
for (Searchpath sp : _valid_searchpaths) {
std::string path = FioGetDirectory(sp, LANG_DIR);
GetLanguageList(path.c_str());
}
@@ -1964,6 +1979,10 @@ void InitializeLanguagePacks()
}
if (strcmp (lng.isocode, "en_GB") == 0) en_GB_fallback = &lng;
/* Only auto-pick finished translations */
if (!lng.IsReasonablyFinished()) continue;
if (strncmp(lng.isocode, lang, 5) == 0) chosen_language = &lng;
if (strncmp(lng.isocode, lang, 2) == 0) language_fallback = &lng;
}
@@ -2017,7 +2036,7 @@ bool MissingGlyphSearcher::FindMissingGlyphs()
default: NOT_REACHED();
}
DEBUG(freetype, 0, "Font is missing glyphs to display char 0x%X in %s font size", c, size_name.c_str());
Debug(freetype, 0, "Font is missing glyphs to display char 0x{:X} in {} font size", (int)c, size_name);
return true;
}
}
@@ -2064,9 +2083,9 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher {
void SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) override
{
#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
strecpy(settings->small.font, font_name, lastof(settings->small.font));
strecpy(settings->medium.font, font_name, lastof(settings->medium.font));
strecpy(settings->large.font, font_name, lastof(settings->large.font));
settings->small.font = font_name;
settings->medium.font = font_name;
settings->large.font = font_name;
settings->small.os_handle = os_data;
settings->medium.os_handle = os_data;
@@ -2097,15 +2116,14 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
if (bad_font) {
/* We found an unprintable character... lets try whether we can find
* a fallback font that can print the characters in the current language. */
FreeTypeSettings backup;
memcpy(&backup, &_freetype, sizeof(backup));
FreeTypeSettings backup = _freetype;
_freetype.mono.os_handle = nullptr;
_freetype.medium.os_handle = nullptr;
bad_font = !SetFallbackFont(&_freetype, _langpack.langpack->isocode, _langpack.langpack->winlangid, searcher);
memcpy(&_freetype, &backup, sizeof(backup));
_freetype = backup;
if (!bad_font) {
/* Show that we loaded fallback font. To do this properly we have