diff --git a/src/language.h b/src/language.h --- a/src/language.h +++ b/src/language.h @@ -21,6 +21,13 @@ static const uint8 CASE_GENDER_LEN = 16; static const uint8 MAX_NUM_GENDERS = 8; ///< Maximum number of supported genders. static const uint8 MAX_NUM_CASES = 16; ///< Maximum number of supported cases. +static const uint TAB_SIZE_OFFSET = 0; ///< The offset for the tab size. +static const uint TAB_SIZE_BITS = 11; ///< The number of bits used for the tab size. +static const uint TAB_SIZE = 1 << TAB_SIZE_BITS; ///< The number of values in a tab. +static const uint TAB_COUNT_OFFSET = TAB_SIZE_BITS; ///< The offset for the tab count. +static const uint TAB_COUNT_BITS = 5; ///< The number of bits used for the amount of tabs. +static const uint TAB_COUNT = 1 << TAB_COUNT_BITS; ///< The amount of tabs. + /** Header of a language file. */ struct LanguagePackHeader { static const uint32 IDENT = 0x474E414C; ///< Identifier for OpenTTD language files, big endian for "LANG" @@ -30,7 +37,7 @@ struct LanguagePackHeader { char name[32]; ///< the international name of this language char own_name[32]; ///< the localized name of this language char isocode[16]; ///< the ISO code for the language (not country code) - uint16 offsets[32]; ///< the offsets + uint16 offsets[TAB_COUNT]; ///< the offsets /** Thousand separator used for anything not currencies */ char digit_group_separator[8]; diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp --- a/src/strgen/strgen.cpp +++ b/src/strgen/strgen.cpp @@ -529,7 +529,7 @@ int CDECL main(int argc, char *argv[]) mkpath(pathbuf, lengthof(pathbuf), src_dir, "english.txt"); /* parse master file */ - StringData data; + StringData data(TAB_COUNT); FileStringReader master_reader(data, pathbuf, true, false); master_reader.ParseFile(); if (_errors != 0) return 1; @@ -546,7 +546,7 @@ int CDECL main(int argc, char *argv[]) mkpath(pathbuf, lengthof(pathbuf), src_dir, "english.txt"); - StringData data; + StringData data(TAB_COUNT); /* parse master file and check if target file is correct */ FileStringReader master_reader(data, pathbuf, true, false); master_reader.ParseFile(); diff --git a/src/strgen/strgen.h b/src/strgen/strgen.h --- a/src/strgen/strgen.h +++ b/src/strgen/strgen.h @@ -39,15 +39,13 @@ struct LangString { /** Information about the currently known strings. */ struct StringData { - static const uint STRINGS_IN_TAB = 2048; - LangString **strings; ///< Array of all known strings. uint16 *hash_heads; ///< Hash table for the strings. size_t tabs; ///< The number of 'tabs' of strings. size_t max_strings; ///< The maxmimum number of strings. int next_string_id; ///< The next string ID to allocate. - StringData(size_t tabs = 32); + StringData(size_t tabs); ~StringData(); void FreeTranslation(); uint HashStr(const char *s) const; @@ -134,8 +132,8 @@ struct LanguageWriter { /** Especially destroy the subclasses. */ virtual ~LanguageWriter() {} - void WriteLength(uint length); - void WriteLang(const StringData &data); + virtual void WriteLength(uint length); + virtual void WriteLang(const StringData &data); }; void CDECL strgen_warning(const char *s, ...) WARN_FORMAT(1, 2); diff --git a/src/strgen/strgen_base.cpp b/src/strgen/strgen_base.cpp --- a/src/strgen/strgen_base.cpp +++ b/src/strgen/strgen_base.cpp @@ -89,7 +89,7 @@ void LangString::FreeTranslation() * Create a new string data container. * @param max_strings The maximum number of strings. */ -StringData::StringData(size_t tabs) : tabs(tabs), max_strings(tabs * STRINGS_IN_TAB) +StringData::StringData(size_t tabs) : tabs(tabs), max_strings(tabs * TAB_SIZE) { this->strings = CallocT(max_strings); this->hash_heads = CallocT(max_strings); @@ -215,7 +215,7 @@ uint StringData::Version() const uint StringData::CountInUse(uint tab) const { int i; - for (i = STRINGS_IN_TAB; --i >= 0;) if (this->strings[(tab * STRINGS_IN_TAB) + i] != NULL) break; + for (i = TAB_SIZE; --i >= 0;) if (this->strings[(tab * TAB_SIZE) + i] != NULL) break; return i + 1; } @@ -938,7 +938,7 @@ void LanguageWriter::WriteLang(const Str _lang.offsets[tab] = TO_LE16(n); for (uint j = 0; j != in_use[tab]; j++) { - const LangString *ls = data.strings[(tab * StringData::STRINGS_IN_TAB) + j]; + const LangString *ls = data.strings[(tab * TAB_SIZE) + j]; if (ls != NULL && ls->translated == NULL) _lang.missing++; } } @@ -953,7 +953,7 @@ void LanguageWriter::WriteLang(const Str for (size_t tab = 0; tab < data.tabs; tab++) { for (uint j = 0; j != in_use[tab]; j++) { - const LangString *ls = data.strings[(tab * StringData::STRINGS_IN_TAB) + j]; + const LangString *ls = data.strings[(tab * TAB_SIZE) + j]; const Case *casep; const char *cmdp; diff --git a/src/strings.cpp b/src/strings.cpp --- a/src/strings.cpp +++ b/src/strings.cpp @@ -132,20 +132,20 @@ struct LanguagePack : public LanguagePac static char **_langpack_offs; static LanguagePack *_langpack; -static uint _langtab_num[32]; ///< Offset into langpack offs -static uint _langtab_start[32]; ///< Offset into langpack offs +static uint _langtab_num[TAB_COUNT]; ///< Offset into langpack offs +static uint _langtab_start[TAB_COUNT]; ///< Offset into langpack offs static bool _keep_gender_data = false; ///< Should we retain the gender data in the current string? const char *GetStringPtr(StringID string) { - switch (GB(string, 11, 5)) { + switch (GB(string, TAB_COUNT_OFFSET, TAB_COUNT_BITS)) { /* GetGRFStringPtr doesn't handle 0xD4xx ids, we need to convert those to 0xD0xx. */ - case 26: return GetStringPtr(GetGRFStringID(0, 0xD000 + GB(string, 0, 10))); - case 28: return GetGRFStringPtr(GB(string, 0, 11)); - case 29: return GetGRFStringPtr(GB(string, 0, 11) + 0x0800); - case 30: return GetGRFStringPtr(GB(string, 0, 11) + 0x1000); - default: return _langpack_offs[_langtab_start[string >> 11] + (string & 0x7FF)]; + case 26: return GetStringPtr(GetGRFStringID(0, 0xD000 + GB(string, TAB_SIZE_OFFSET, 10))); + case 28: return GetGRFStringPtr(GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS)); + case 29: return GetGRFStringPtr(GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS) + 0x0800); + case 30: return GetGRFStringPtr(GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS) + 0x1000); + default: return _langpack_offs[_langtab_start[GB(string, TAB_COUNT_OFFSET, TAB_COUNT_BITS)] + GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS)]; } } @@ -162,8 +162,8 @@ char *GetStringWithArgs(char *buffr, Str { if (string == 0) return GetStringWithArgs(buffr, STR_UNDEFINED, args, last); - uint index = GB(string, 0, 11); - uint tab = GB(string, 11, 5); + uint index = GB(string, TAB_SIZE_OFFSET, TAB_SIZE_BITS); + uint tab = GB(string, TAB_COUNT_OFFSET, TAB_COUNT_BITS); switch (tab) { case 4: @@ -1536,13 +1536,13 @@ bool ReadLanguagePack(const LanguageMeta } #if TTD_ENDIAN == TTD_BIG_ENDIAN - for (uint i = 0; i < 32; i++) { + for (uint i = 0; i < TAB_COUNT; i++) { lang_pack->offsets[i] = ReadLE16Aligned(&lang_pack->offsets[i]); } #endif /* TTD_ENDIAN == TTD_BIG_ENDIAN */ uint count = 0; - for (uint i = 0; i < 32; i++) { + for (uint i = 0; i < TAB_COUNT; i++) { uint num = lang_pack->offsets[i]; _langtab_start[i] = count; _langtab_num[i] = num; @@ -1849,12 +1849,12 @@ class LanguagePackGlyphSearcher : public /* virtual */ const char *NextString() { - if (this->i >= 32) return NULL; + if (this->i >= TAB_COUNT) return NULL; const char *ret = _langpack_offs[_langtab_start[i] + j]; this->j++; - while (this->j >= _langtab_num[this->i] && this->i < 32) { + while (this->j >= _langtab_num[this->i] && this->i < TAB_COUNT) { i++; j = 0; }