From 795bdf886b676db178d90270eebbdb1fc0ff0642 Mon Sep 17 00:00:00 2001 From: Dav999-v Date: Thu, 1 Dec 2022 01:27:30 +0100 Subject: [PATCH] Add support for string cases in strings.xml (gendered Rescued/Missing) I wanted to not complicate the system with different string cases (like cgettext) if possible, and I have been able to keep the main strings a simple English=Translation mapping thus far, but apparently strings like "Rescued!" (which are one string in English), have to be translated for the correct gender in some languages. So this was a good time to add support for string cases anyway. It's a number that can be given to a string to specify the specific case it's used, to disambiguate identical English keys. In the case of "Rescued!" and "Missing...", male versions of the string are case 1, female versions are case 2, and Viridian being missing is case 3. Of course, if a language doesn't need to use different variants, it can simply fill in the same string for the different cases. If any other string needs to switch to different cases: distinguish them in the English strings.xml with the case="N" attribute (N=1 and higher), sync language files from the translator menu (existing translations for the uncased string will simply be copied to all cases) and change loc::gettext("...") to loc::gettext_case("...", 1), loc::gettext_case("...", 2), etc. --- desktop_version/lang/en/strings.xml | 7 +++- desktop_version/lang/eo/strings.xml | 7 +++- desktop_version/lang/es/strings.xml | 7 +++- desktop_version/lang/nl/strings.xml | 7 +++- desktop_version/src/Graphics.cpp | 42 +++++++++++++++++---- desktop_version/src/Graphics.h | 5 +-- desktop_version/src/Localization.cpp | 22 +++++++++++ desktop_version/src/Localization.h | 1 + desktop_version/src/LocalizationMaint.cpp | 28 +++++++++++++- desktop_version/src/LocalizationStorage.cpp | 33 +++++++++++++--- desktop_version/src/Render.cpp | 12 ++---- 11 files changed, 137 insertions(+), 34 deletions(-) diff --git a/desktop_version/lang/en/strings.xml b/desktop_version/lang/en/strings.xml index 4b6ab504..79f47aff 100644 --- a/desktop_version/lang/en/strings.xml +++ b/desktop_version/lang/en/strings.xml @@ -445,8 +445,11 @@ - - + + + + + diff --git a/desktop_version/lang/eo/strings.xml b/desktop_version/lang/eo/strings.xml index 91573c9a..4f6f4a4a 100644 --- a/desktop_version/lang/eo/strings.xml +++ b/desktop_version/lang/eo/strings.xml @@ -445,8 +445,11 @@ - - + + + + + diff --git a/desktop_version/lang/es/strings.xml b/desktop_version/lang/es/strings.xml index 039831d9..2018dbad 100644 --- a/desktop_version/lang/es/strings.xml +++ b/desktop_version/lang/es/strings.xml @@ -445,8 +445,11 @@ - - + + + + + diff --git a/desktop_version/lang/nl/strings.xml b/desktop_version/lang/nl/strings.xml index cc9f0f78..ef22fdd0 100644 --- a/desktop_version/lang/nl/strings.xml +++ b/desktop_version/lang/nl/strings.xml @@ -445,8 +445,11 @@ - - + + + + + diff --git a/desktop_version/src/Graphics.cpp b/desktop_version/src/Graphics.cpp index 2bbab854..8e504b7a 100644 --- a/desktop_version/src/Graphics.cpp +++ b/desktop_version/src/Graphics.cpp @@ -966,30 +966,58 @@ void Graphics::printcrewnamedark( int x, int y, int t ) } } -void Graphics::printcrewnamestatus( int x, int y, int t ) +void Graphics::printcrewnamestatus( int x, int y, int t, bool rescued ) { //Print the status of crew member t in the right colour + int r, g, b; + char gender; + switch(t) { case 0: - Print(x, y, loc::gettext("(that's you!)"), 12, 140, 140,false); + r=12; g=140, b=140; + gender = 3; break; case 1: - Print(x, y, loc::gettext("Rescued!"), 140, 12, 140,false); + r=140; g=12; b=140; + gender = 2; break; case 2: - Print(x, y, loc::gettext("Rescued!"), 140, 140, 12,false); + r=140; g=140; b=12; + gender = 1; break; case 3: - Print(x, y, loc::gettext("Rescued!"), 140, 12, 12,false); + r=140; g=12; b=12; + gender = 1; break; case 4: - Print(x, y, loc::gettext("Rescued!"), 12, 140, 12,false); + r=12; g=140; b=12; + gender = 1; break; case 5: - Print(x, y, loc::gettext("Rescued!"), 12, 12, 140,false); + r=12; g=12; b=140; + gender = 2; break; + default: + return; } + + const char* status_text; + if (gender == 3 && rescued) + { + status_text = loc::gettext("(that's you!)"); + } + else if (rescued) + { + status_text = loc::gettext_case("Rescued!", gender); + } + else + { + r=64; g=64; b=64; + status_text = loc::gettext_case("Missing...", gender); + } + + Print(x, y, status_text, r, g, b, false); } void Graphics::drawsprite( int x, int y, int t, int r, int g, int b ) diff --git a/desktop_version/src/Graphics.h b/desktop_version/src/Graphics.h index e5dd16b1..e6ddec13 100644 --- a/desktop_version/src/Graphics.h +++ b/desktop_version/src/Graphics.h @@ -144,11 +144,10 @@ public: void drawsprite(int x, int y, int t, Uint32 c); void printcrewname(int x, int y, int t); - - void printcrewnamestatus(int x, int y, int t); - void printcrewnamedark(int x, int y, int t); + void printcrewnamestatus(int x, int y, int t, bool rescued); + void map_tab(int opt, const char* text, bool selected = false); void map_option(int opt, int num_opts, const std::string& text, bool selected = false); diff --git a/desktop_version/src/Localization.cpp b/desktop_version/src/Localization.cpp index 298a9c1b..01786d74 100644 --- a/desktop_version/src/Localization.cpp +++ b/desktop_version/src/Localization.cpp @@ -50,6 +50,28 @@ const char* gettext(const char* eng) return map_lookup_text(map_translation, eng, eng); } +const char* gettext_case(const char* eng, char textcase) +{ + if (lang == "en") + { + return eng; + } + if (textcase == 0) + { + return gettext(eng); + } + + char* eng_prefixed = add_disambiguator(textcase, eng, NULL); + if (eng_prefixed == NULL) + { + return eng; + } + + const char* tra = map_lookup_text(map_translation, eng_prefixed, eng); + SDL_free(eng_prefixed); + return tra; +} + static const char* gettext_plural_english(const char* eng_plural, const char* eng_singular, int n) { /* Do be consistent with negative number handling for other languages... */ diff --git a/desktop_version/src/Localization.h b/desktop_version/src/Localization.h index 9be0fbfa..4d05e43e 100644 --- a/desktop_version/src/Localization.h +++ b/desktop_version/src/Localization.h @@ -74,6 +74,7 @@ extern int n_untranslated[COUNT_UNTRANSLATED_INDEX]; const LangMeta* get_langmeta(void); const char* gettext(const char* eng); +const char* gettext_case(const char* eng, char textcase); const char* gettext_plural(const char* eng_plural, const char* eng_singular, int count); void gettext_plural_fill(char* buf, size_t buf_len, const char* eng_plural, const char* eng_singular, const char* args_index, ...); std::string getnumber(int n); diff --git a/desktop_version/src/LocalizationMaint.cpp b/desktop_version/src/LocalizationMaint.cpp index 4048dde8..26f2f9bc 100644 --- a/desktop_version/src/LocalizationMaint.cpp +++ b/desktop_version/src/LocalizationMaint.cpp @@ -88,7 +88,31 @@ static void sync_lang_file(const std::string& langcode) const char* eng = pElem->Attribute("english"); if (eng != NULL) { - pElem->SetAttribute("translation", map_lookup_text(map_translation, eng, "")); + char textcase = pElem->UnsignedAttribute("case", 0); + const char* tra; + if (textcase == 0) + { + tra = map_lookup_text(map_translation, eng, ""); + } + else + { + char* eng_prefixed = add_disambiguator(textcase, eng, NULL); + if (eng_prefixed == NULL) + { + /* Are we out of memory? Stop, don't blank our language files... */ + return; + } + /* Note the fallback: if this string used to not be cased and now it is, + * simply fill in the old single variant we already had. */ + tra = map_lookup_text( + map_translation, + eng_prefixed, + map_lookup_text(map_translation, eng, "") + ); + SDL_free(eng_prefixed); + } + + pElem->SetAttribute("translation", tra); } } @@ -125,7 +149,7 @@ static void sync_lang_file(const std::string& langcode) char* key = add_disambiguator(form_id+1, eng_plural, NULL); if (key == NULL) { - /* Are we out of memory? Stop, don't blank our language files... */ + /* Out of memory or something, stop */ return; } diff --git a/desktop_version/src/LocalizationStorage.cpp b/desktop_version/src/LocalizationStorage.cpp index 428857d1..de2153bb 100644 --- a/desktop_version/src/LocalizationStorage.cpp +++ b/desktop_version/src/LocalizationStorage.cpp @@ -416,12 +416,33 @@ static void loadtext_strings(bool check_max) const char* eng = pElem->Attribute("english"); const char* tra = pElem->Attribute("translation"); - map_store_translation( - &textbook_main, - map_translation, - eng, - tra - ); + char textcase = pElem->UnsignedAttribute("case", 0); + + if (textcase == 0) + { + map_store_translation( + &textbook_main, + map_translation, + eng, + tra + ); + } + else + { + /* Only prefix with a disambiguator if a specific case number is set */ + char* eng_prefixed = add_disambiguator(textcase, eng, NULL); + if (eng_prefixed == NULL) + { + continue; + } + map_store_translation( + &textbook_main, + map_translation, + eng_prefixed, + tra + ); + SDL_free(eng_prefixed); + } /* Only tally an untranslated string if English isn't blank */ if (eng != NULL && eng[0] != '\0') diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index d9f9015e..8e514454 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -2579,25 +2579,23 @@ void maprender(void) if (game.crewstats[(2-i)]) { graphics.printcrewname(44, 32 + (i * 64)+4+10, 2-i); - graphics.printcrewnamestatus(44, 32 + (i * 64)+4, 2-i); } else { graphics.printcrewnamedark(44, 32 + (i * 64)+4+10, 2-i); - graphics.Print(44, 32 + (i * 64) + 4, loc::gettext("Missing..."), 64,64,64); } + graphics.printcrewnamestatus(44, 32 + (i * 64)+4, 2-i, game.crewstats[(2-i)]); graphics.drawcrewman(16+160, 32 + (i * 64), (2-i)+3, game.crewstats[(2-i)+3]); if (game.crewstats[(2-i)+3]) { graphics.printcrewname(44+160, 32 + (i * 64)+4+10, (2-i)+3); - graphics.printcrewnamestatus(44+160, 32 + (i * 64)+4, (2-i)+3); } else { graphics.printcrewnamedark(44+160, 32 + (i * 64)+4+10, (2-i)+3); - graphics.Print(44+160, 32 + (i * 64) + 4, loc::gettext("Missing..."), 64,64,64); } + graphics.printcrewnamestatus(44+160, 32 + (i * 64)+4, (2-i)+3, game.crewstats[(2-i)+3]); } } else @@ -2608,25 +2606,23 @@ void maprender(void) if (game.crewstats[i]) { graphics.printcrewname(44, 32 + (i * 64)+4, i); - graphics.printcrewnamestatus(44, 32 + (i * 64)+4+10, i); } else { graphics.printcrewnamedark(44, 32 + (i * 64)+4, i); - graphics.Print(44, 32 + (i * 64) + 4 + 10, loc::gettext("Missing..."), 64,64,64); } + graphics.printcrewnamestatus(44, 32 + (i * 64)+4+10, i, game.crewstats[i]); graphics.drawcrewman(16+160, 32 + (i * 64), i+3, game.crewstats[i+3]); if (game.crewstats[i+3]) { graphics.printcrewname(44+160, 32 + (i * 64)+4, i+3); - graphics.printcrewnamestatus(44+160, 32 + (i * 64)+4+10, i+3); } else { graphics.printcrewnamedark(44+160, 32 + (i * 64)+4, i+3); - graphics.Print(44+160, 32 + (i * 64) + 4 + 10, loc::gettext("Missing..."), 64,64,64); } + graphics.printcrewnamestatus(44+160, 32 + (i * 64)+4+10, i+3, game.crewstats[i+3]); } } }