diff --git a/desktop_version/lang/ca/strings.xml b/desktop_version/lang/ca/strings.xml index 803e9a24..1e624d40 100755 --- a/desktop_version/lang/ca/strings.xml +++ b/desktop_version/lang/ca/strings.xml @@ -165,6 +165,10 @@ + + + + @@ -544,8 +548,6 @@ - - diff --git a/desktop_version/lang/en/strings.xml b/desktop_version/lang/en/strings.xml index 5b451028..b9e5e38e 100644 --- a/desktop_version/lang/en/strings.xml +++ b/desktop_version/lang/en/strings.xml @@ -165,6 +165,10 @@ + + + + diff --git a/desktop_version/lang/eo/strings.xml b/desktop_version/lang/eo/strings.xml index 23953c75..2be7c75c 100644 --- a/desktop_version/lang/eo/strings.xml +++ b/desktop_version/lang/eo/strings.xml @@ -165,6 +165,10 @@ + + + + diff --git a/desktop_version/lang/es/strings.xml b/desktop_version/lang/es/strings.xml index 4334dfe7..03d53eb9 100644 --- a/desktop_version/lang/es/strings.xml +++ b/desktop_version/lang/es/strings.xml @@ -165,6 +165,10 @@ + + + + diff --git a/desktop_version/lang/nl/strings.xml b/desktop_version/lang/nl/strings.xml index f5227f56..4299be01 100644 --- a/desktop_version/lang/nl/strings.xml +++ b/desktop_version/lang/nl/strings.xml @@ -165,6 +165,10 @@ + + + + diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index 29f65f47..80fa3a65 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -302,6 +302,7 @@ void Game::init(void) start_translator_exploring = false; translator_exploring = false; translator_exploring_allowtele = false; + translator_cutscene_test = false; totalflips = 0; hardestroom = "Welcome Aboard"; @@ -6448,6 +6449,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) option(loc::gettext("translate room names")); option(loc::gettext("explore game")); option(loc::gettext("menu test")); + option(loc::gettext("cutscene test"), loc::lang != "en"); option(loc::gettext("limits check")); option(loc::gettext("return")); menuyoff = 0; @@ -6473,6 +6475,38 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) option(loc::gettext("return")); menuyoff = -20; break; + case Menu::translator_options_cutscenetest: + for ( + size_t i = (cutscenetest_menu_page*14); + i < (cutscenetest_menu_page*14)+14 && i < loc::testable_script_ids.size(); + i++ + ) + { + option(loc::testable_script_ids[i].c_str()); + } + if((cutscenetest_menu_page*14)+14 < loc::testable_script_ids.size()) + { + option(loc::gettext("next page")); + } + else + { + option(loc::gettext("first page")); + } + if (cutscenetest_menu_page == 0) + { + option(loc::gettext("last page")); + } + else + { + option(loc::gettext("previous page")); + } + option(loc::gettext("from clipboard")); + option(loc::gettext("return")); + + menuxoff = 20; + menuyoff = 55-(menuoptions.size()*10); + menuspacing = 5; + return; // skip automatic centering, will turn out bad with scripts list case Menu::translator_maintenance: option(loc::gettext("sync language files")); option(loc::gettext("global statistics"), false); @@ -6993,7 +7027,11 @@ void Game::quittomenu(void) //or "who do you want to play the level with?" //or "do you want cutscenes?" //or the confirm-load-quicksave menu - if (translator_exploring) + if (translator_cutscene_test) + { + returntomenu(Menu::translator_options_cutscenetest); + } + else if (translator_exploring) { returntomenu(Menu::translator_options_exploregame); } diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h index 33c3cbfa..a93ed3e0 100644 --- a/desktop_version/src/Game.h +++ b/desktop_version/src/Game.h @@ -66,6 +66,7 @@ namespace Menu translator_options_limitscheck, translator_options_stats, translator_options_exploregame, + translator_options_cutscenetest, translator_maintenance, translator_maintenance_sync, translator_error_setlangwritedir, @@ -361,6 +362,10 @@ public: bool start_translator_exploring; bool translator_exploring; bool translator_exploring_allowtele; + bool translator_cutscene_test; + + size_t cutscenetest_menu_page; + std::string cutscenetest_menu_play_id; int creditposition; int oldcreditposition; @@ -493,7 +498,7 @@ public: bool inline inspecial(void) { - return inintermission || insecretlab || intimetrial || nodeathmode; + return inintermission || insecretlab || intimetrial || nodeathmode || translator_exploring; } bool incompetitive(void); diff --git a/desktop_version/src/Graphics.cpp b/desktop_version/src/Graphics.cpp index 8e504b7a..429a6b03 100644 --- a/desktop_version/src/Graphics.cpp +++ b/desktop_version/src/Graphics.cpp @@ -1834,6 +1834,14 @@ void Graphics::drawmenu(int cr, int cg, int cb, enum Menu::MenuName menu) } } #endif + if (menu == Menu::translator_options_cutscenetest) + { + size_t separator = 4; + if (game.menuoptions.size() - i <= separator) + { + y += 4; + } + } char buffer[MENU_TEXT_BYTES]; if ((int) i == game.currentmenuoption && game.slidermode == SLIDER_NONE) diff --git a/desktop_version/src/Input.cpp b/desktop_version/src/Input.cpp index 91b66a3c..77030901 100644 --- a/desktop_version/src/Input.cpp +++ b/desktop_version/src/Input.cpp @@ -1182,7 +1182,7 @@ static void menuactionpress(void) game.savestatsandsettings_menu(); break; case 2: - // enter game + // explore game music.playef(11); game.createmenu(Menu::translator_options_exploregame); map.nexttowercolour(); @@ -1195,6 +1195,21 @@ static void menuactionpress(void) map.nexttowercolour(); break; case 4: + // cutscene test + if (loc::lang == "en") + { + music.playef(2); + } + else + { + music.playef(11); + game.cutscenetest_menu_page = 0; + loc::populate_testable_script_ids(); + game.createmenu(Menu::translator_options_cutscenetest); + map.nexttowercolour(); + } + break; + case 5: // limits check music.playef(11); loc::local_limits_check(); @@ -1238,46 +1253,38 @@ static void menuactionpress(void) switch (game.currentmenuoption) { case 0: - // SS1 game.start_translator_exploring = true; - startmode(3); + startmode(Start_TIMETRIAL_SPACESTATION1); break; case 1: - // Lab game.start_translator_exploring = true; - startmode(4); + startmode(Start_TIMETRIAL_LABORATORY); break; case 2: - // Tower game.start_translator_exploring = true; - startmode(5); + startmode(Start_TIMETRIAL_TOWER); break; case 3: - // SS2 game.start_translator_exploring = true; - startmode(6); + startmode(Start_TIMETRIAL_SPACESTATION2); break; case 4: - // WZ game.start_translator_exploring = true; - startmode(7); + startmode(Start_TIMETRIAL_WARPZONE); break; case 5: - // Int 1 game.createmenu(Menu::playint1); game.start_translator_exploring = true; map.nexttowercolour(); break; case 6: - // Int 2 game.createmenu(Menu::playint2); game.start_translator_exploring = true; map.nexttowercolour(); break; case 7: - // Final game.start_translator_exploring = true; - startmode(8); + startmode(Start_TIMETRIAL_FINALLEVEL); break; default: // return @@ -1286,6 +1293,59 @@ static void menuactionpress(void) break; } break; + case Menu::translator_options_cutscenetest: + if (game.currentmenuoption == (int)game.menuoptions.size()-4) + { + // next page + music.playef(11); + if ((size_t) ((game.cutscenetest_menu_page*14)+14) >= loc::testable_script_ids.size()) + { + game.cutscenetest_menu_page = 0; + } + else + { + game.cutscenetest_menu_page++; + } + game.createmenu(Menu::translator_options_cutscenetest, true); + game.currentmenuoption=game.menuoptions.size()-4; + map.nexttowercolour(); + } + else if (game.currentmenuoption == (int)game.menuoptions.size()-3) + { + // previous page + music.playef(11); + if (game.cutscenetest_menu_page == 0) + { + game.cutscenetest_menu_page = (loc::testable_script_ids.size()-1)/14; + } + else + { + game.cutscenetest_menu_page--; + } + game.createmenu(Menu::translator_options_cutscenetest, true); + game.currentmenuoption=game.menuoptions.size()-3; + map.nexttowercolour(); + } + else if (game.currentmenuoption == (int)game.menuoptions.size()-2) + { + // play the cutscene, from clipboard + game.cutscenetest_menu_play_id = std::string(SDL_GetClipboardText()); + startmode(Start_CUTSCENETEST); + } + else if (game.currentmenuoption == (int)game.menuoptions.size()-1) + { + // go back to menu + music.playef(11); + game.returnmenu(); + map.nexttowercolour(); + } + else + { + // play the cutscene! + game.cutscenetest_menu_play_id = loc::testable_script_ids[(game.cutscenetest_menu_page*14)+game.currentmenuoption]; + startmode(Start_CUTSCENETEST); + } + break; case Menu::translator_maintenance: music.playef(11); switch (game.currentmenuoption) diff --git a/desktop_version/src/Localization.cpp b/desktop_version/src/Localization.cpp index 01786d74..2f7ebc3b 100644 --- a/desktop_version/src/Localization.cpp +++ b/desktop_version/src/Localization.cpp @@ -21,6 +21,7 @@ std::vector languagelist; int languagelist_curlang; bool show_translator_menu = false; size_t limitscheck_current_overflow; +std::vector testable_script_ids; int n_untranslated_roomnames = 0; int n_unexplained_roomnames = 0; diff --git a/desktop_version/src/Localization.h b/desktop_version/src/Localization.h index 4d05e43e..5a503732 100644 --- a/desktop_version/src/Localization.h +++ b/desktop_version/src/Localization.h @@ -52,6 +52,7 @@ extern std::vector languagelist; extern int languagelist_curlang; extern bool show_translator_menu; extern size_t limitscheck_current_overflow; +extern std::vector testable_script_ids; extern int n_untranslated_roomnames; extern int n_unexplained_roomnames; diff --git a/desktop_version/src/LocalizationMaint.cpp b/desktop_version/src/LocalizationMaint.cpp index 26f2f9bc..450d0527 100644 --- a/desktop_version/src/LocalizationMaint.cpp +++ b/desktop_version/src/LocalizationMaint.cpp @@ -6,6 +6,7 @@ #include "FileSystemUtils.h" #include "Graphics.h" +#include "Script.h" #include "Vlogging.h" #include "XMLUtils.h" @@ -419,4 +420,76 @@ void global_limits_check(void) limitscheck_current_overflow = 0; } +void populate_testable_script_ids(void) +{ + testable_script_ids.clear(); + + tinyxml2::XMLDocument doc; + tinyxml2::XMLHandle hDoc(&doc); + tinyxml2::XMLElement* pElem; + + if (!load_lang_doc("cutscenes", doc)) + { + return; + } + + FOR_EACH_XML_ELEMENT(hDoc, pElem) + { + EXPECT_ELEM(pElem, "cutscene"); + + const char* id = pElem->Attribute("id"); + if (id != NULL) + { + testable_script_ids.push_back(id); + } + } +} + +bool populate_cutscene_test(const char* script_id) +{ + tinyxml2::XMLDocument doc; + tinyxml2::XMLHandle hDoc(&doc); + tinyxml2::XMLElement* pElem; + + if (!load_lang_doc("cutscenes", doc)) + { + return false; + } + + const char* original = get_level_original_lang(hDoc); + + FOR_EACH_XML_ELEMENT(hDoc, pElem) + { + EXPECT_ELEM(pElem, "cutscene"); + + if (SDL_strcmp(pElem->Attribute("id"), script_id) != 0) + { + /* Not the correct cutscene */ + continue; + } + + tinyxml2::XMLElement* subElem; + FOR_EACH_XML_SUB_ELEMENT(pElem, subElem) + { + EXPECT_ELEM(subElem, "dialogue"); + + const char* tra = subElem->Attribute("translation"); + const char* speaker = subElem->Attribute("speaker"); + const char* eng = subElem->Attribute(original); + if (tra != NULL && tra[0] != '\0' && speaker != NULL && eng != NULL) + { + script.add_test_line( + speaker, + eng, + subElem->UnsignedAttribute("case", 1) + ); + } + } + + return true; + } + + return false; +} + } /* namespace loc */ diff --git a/desktop_version/src/LocalizationMaint.h b/desktop_version/src/LocalizationMaint.h index f9038105..b8c93a0a 100644 --- a/desktop_version/src/LocalizationMaint.h +++ b/desktop_version/src/LocalizationMaint.h @@ -12,6 +12,9 @@ bool save_roomname_explanation_to_files(bool custom_level, int roomx, int roomy, void local_limits_check(void); void global_limits_check(void); +void populate_testable_script_ids(void); +bool populate_cutscene_test(const char* script_id); + } /* namespace loc */ #endif /* LOCALIZATIONMAINT_H */ diff --git a/desktop_version/src/LocalizationStorage.cpp b/desktop_version/src/LocalizationStorage.cpp index de2153bb..3835876c 100644 --- a/desktop_version/src/LocalizationStorage.cpp +++ b/desktop_version/src/LocalizationStorage.cpp @@ -2,8 +2,6 @@ #include "Localization.h" #include "LocalizationStorage.h" -#include - #include "Constants.h" #include "CustomLevels.h" #include "FileSystemUtils.h" @@ -554,7 +552,7 @@ static bool get_level_lang_path(bool custom_level, const char* cat, std::string& } } -static const char* get_level_original_lang(tinyxml2::XMLHandle& hDoc) +const char* get_level_original_lang(tinyxml2::XMLHandle& hDoc) { /* cutscenes and roomnames files can specify the original language as * an attribute of the root tag to change the attribute names of the diff --git a/desktop_version/src/LocalizationStorage.h b/desktop_version/src/LocalizationStorage.h index 1437b0fe..8b53f8f2 100644 --- a/desktop_version/src/LocalizationStorage.h +++ b/desktop_version/src/LocalizationStorage.h @@ -1,6 +1,8 @@ #ifndef LOCALIZATIONSTORAGE_H #define LOCALIZATIONSTORAGE_H +#include + #include "Textbook.h" #include "XMLUtils.h" @@ -65,6 +67,8 @@ unsigned char form_for_count(int n); void unloadtext_custom(void); void resettext(bool final_shutdown); +const char* get_level_original_lang(tinyxml2::XMLHandle& hDoc); + bool store_roomname_translation(bool custom_level, int roomx, int roomy, const char* tra, const char* explanation); bool fix_room_coords(bool custom_level, int* roomx, int* roomy); diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index 8e514454..6ceb7702 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -669,6 +669,10 @@ static void menurender(void) graphics.PrintWrap( -1, 65, loc::gettext("Cycle through most menus in the game. The menus will not actually work, all options take you to the next menu instead. Press Escape to stop."), tr, tg, tb, true); break; case 4: + graphics.bigprint( -1, 30, loc::gettext("Cutscene test"), tr, tg, tb, true); + graphics.PrintWrap( -1, 65, loc::gettext("Display all text boxes from cutscenes.xml. Only tests the basic appearance of each individual text box."), tr, tg, tb, true); + break; + case 5: graphics.bigprint( -1, 30, loc::gettext("Limits check"), tr, tg, tb, true); graphics.PrintWrap( -1, 65, loc::gettext("Find translations that don't fit within their defined bounds."), tr, tg, tb, true); break; diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index d0498b17..7831c924 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -14,6 +14,7 @@ #include "Graphics.h" #include "KeyPoll.h" #include "Localization.h" +#include "LocalizationMaint.h" #include "LocalizationStorage.h" #include "Map.h" #include "Music.h" @@ -2810,6 +2811,16 @@ void scriptclass::startgamemode(const enum StartMode mode) } #endif /* NO_CUSTOM_LEVELS */ + case Start_CUTSCENETEST: + music.fadeout(); + game.translator_exploring = true; + game.translator_cutscene_test = true; + game.startspecial(2); + game.mapheld = true; + + loadtest(game.cutscenetest_menu_play_id); + break; + case Start_QUIT: VVV_unreachable(); } @@ -3056,6 +3067,7 @@ void scriptclass::hardreset(void) game.translator_exploring = game.start_translator_exploring; game.start_translator_exploring = false; game.translator_exploring_allowtele = false; + game.translator_cutscene_test = false; game.totalflips = 0; game.hardestroom = loc::gettext_roomname(false, 13, 5, "Welcome Aboard", false); @@ -3490,3 +3502,34 @@ void scriptclass::loadcustom(const std::string& t) add("untilbars()"); } } + +void scriptclass::add_test_line(const std::string& speaker, const std::string& english, char textcase) +{ + if (speaker == "gray") + { + add("squeak(terminal)"); + } + else + { + add("squeak("+speaker+")"); + } + add("textcase("+help.String(textcase)+")"); + add("text("+speaker+",0,0,1)"); + add(english); + add("position(center)"); + add("speak_active"); +} + +void scriptclass::loadtest(const std::string& name) +{ + // Another magic function, that turns language files into a demo script + position = 0; + commands.clear(); + scriptname = name; + running = true; + + loc::populate_cutscene_test(name.c_str()); + + add("endtext"); + add("gamestate(3100)"); +} diff --git a/desktop_version/src/Script.h b/desktop_version/src/Script.h index 4c29f2e6..e18319da 100644 --- a/desktop_version/src/Script.h +++ b/desktop_version/src/Script.h @@ -44,6 +44,7 @@ enum StartMode Start_CUSTOM, Start_CUSTOM_QUICKSAVE, Start_QUIT, + Start_CUTSCENETEST, Start_FIRST_NODEATHMODE = Start_NODEATHMODE_WITHCUTSCENES, Start_LAST_NODEATHMODE = Start_NODEATHMODE_NOCUTSCENES, @@ -66,6 +67,9 @@ public: void loadother(const char* t); void loadcustom(const std::string& t); + void add_test_line(const std::string& speaker, const std::string& english, char textcase); + void loadtest(const std::string& name); + void inline add(const std::string& t) { commands.push_back(t);