changeset 16484:92174638bc84 draft

(svn r21208) -Add: [NewGRF] Mapping information w.r.t. a translation's case and gender names
author rubidium <rubidium@openttd.org>
date Tue, 16 Nov 2010 12:47:22 +0000
parents 4a73d307d9f2
children d10cc518045a
files src/newgrf.cpp src/newgrf.h src/newgrf_text.h
diffstat 3 files changed, 79 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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 @@
 				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 @@
 				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 @@
 		free(f->filename);
 		free(f->cargo_list);
 		free(f->railtype_list);
+		delete [] f->language_map;
 		free(f);
 	}
 
--- a/src/newgrf.h
+++ b/src/newgrf.h
@@ -123,6 +123,8 @@
 	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
 
--- 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 @@
 
 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 */