diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/newgrf.cpp | 58 | ||||
-rw-r--r-- | src/newgrf.h | 2 | ||||
-rw-r--r-- | src/newgrf_text.h | 19 |
3 files changed, 79 insertions, 0 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp index bb77635d8..6c758c9dd 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -47,6 +47,7 @@ #include "genworld.h" #include "gui.h" #include "vehicle_func.h" +#include "language.h" #include "table/strings.h" #include "table/build_industry.h" @@ -1896,6 +1897,55 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By buf->Skip(4); break; + case 0x13: // Gender translation table + case 0x14: { // Case translation table + uint curidx = gvid + i; // The current index, i.e. language. + const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL; + if (lang == NULL) { + grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx); + /* Skip over the data. */ + while (buf->ReadByte() != 0) { + buf->ReadString(); + } + break; + } + + if (_cur_grffile->language_map == NULL) _cur_grffile->language_map = new LanguageMap[MAX_LANG]; + + byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier. + while (newgrf_id != 0) { + const char *name = buf->ReadString(); // The name for the OpenTTD identifier. + + /* We'll just ignore the UTF8 identifier character. This is (fairly) + * safe as OpenTTD's strings gender/cases are usually in ASCII which + * is just a subset of UTF8, or they need the bigger UTF8 characters + * such as Cyrillic. Thus we will simply assume they're all UTF8. */ + WChar c; + size_t len = Utf8Decode(&c, name); + if (c == NFO_UTF8_IDENTIFIER) name += len; + + LanguageMap::Mapping map; + map.newgrf_id = newgrf_id; + if (prop == 0x13) { + map.openttd_id = lang->GetGenderIndex(name); + if (map.openttd_id >= MAX_NUM_GENDERS) { + grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name); + } else { + *_cur_grffile->language_map[curidx].gender_map.Append() = map; + } + } else { + map.openttd_id = lang->GetCaseIndex(name); + if (map.openttd_id >= MAX_NUM_CASES) { + grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name); + } else { + *_cur_grffile->language_map[curidx].case_map.Append() = map; + } + } + newgrf_id = buf->ReadByte(); + } + break; + } + default: ret = CIR_UNKNOWN; break; @@ -1972,6 +2022,13 @@ static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, B break; } + case 0x13: // Gender translation table + case 0x14: // Case translation table + while (buf->ReadByte() != 0) { + buf->ReadString(); + } + break; + default: ret = CIR_UNKNOWN; break; @@ -6990,6 +7047,7 @@ static void ResetNewGRF() free(f->filename); free(f->cargo_list); free(f->railtype_list); + delete [] f->language_map; free(f); } diff --git a/src/newgrf.h b/src/newgrf.h index 5be03b8c4..4e7ef3f06 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -123,6 +123,8 @@ struct GRFFile { RailTypeLabel *railtype_list; RailType railtype_map[RAILTYPE_END]; + struct LanguageMap *language_map; ///< Mappings related to the languages. + int traininfo_vehicle_pitch; ///< Vertical offset for draing train images in depot GUI and vehicle details uint traininfo_vehicle_width; ///< Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details diff --git a/src/newgrf_text.h b/src/newgrf_text.h index 2865bf706..90fcd719a 100644 --- a/src/newgrf_text.h +++ b/src/newgrf_text.h @@ -14,6 +14,7 @@ #include "string_type.h" #include "strings_type.h" +#include "core/smallvec_type.hpp" /** This character, the thorn ('รพ'), indicates a unicode string to NFO. */ static const WChar NFO_UTF8_IDENTIFIER = 0x00DE; @@ -42,4 +43,22 @@ uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const StringID TTDPStringIDToOTTDStringIDMapping(StringID string); +/** Mapping of language data between a NewGRF and OpenTTD. */ +struct LanguageMap { + /** Mapping between NewGRF and OpenTTD IDs. */ + struct Mapping { + byte newgrf_id; ///< NewGRF's internal ID for a case/gender. + byte openttd_id; ///< OpenTTD's internal ID for a case/gender. + }; + + /* We need a vector and can't use SmallMap due to the fact that for "setting" a + * gender of a string or requesting a case for a substring we want to map from + * the NewGRF's internal ID to OpenTTD's ID whereas for the choice lists we map + * the genders/cases/plural OpenTTD IDs to the NewGRF's internal IDs. In this + * case a NewGRF developer/translator might want a different translation for + * both cases. Thus we are basically implementing a multi-map. */ + SmallVector<Mapping, 1> gender_map; ///< Mapping of NewGRF and OpenTTD IDs for genders. + SmallVector<Mapping, 1> case_map; ///< Mapping of NewGRF and OpenTTD IDs for cases. +}; + #endif /* NEWGRF_TEXT_H */ |