Add cutscene test menu

This allows translators to test all text boxes in the scripts. It
doesn't run the scripts themselves - it only shows the basic appearance
of each text box individually, so context may be lost but it's good to
have a way to see any text boxes that might otherwise not be easily
seen because they require specific circumstances to appear.
This commit is contained in:
Dav999-v 2022-12-24 04:16:56 +01:00 committed by Misa Elizabeth Kai
parent 0ed7717dd5
commit 3937a12a85
18 changed files with 282 additions and 22 deletions

View File

@ -165,6 +165,10 @@
<string english="menu test" translation="prova de menús" explanation="menu option"/>
<string english="Menu test" translation="Prova de menús" explanation="title" max="20"/>
<string english="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." translation="Passeja per la majoria de menús|del joc. Els menús no funcionaran|i totes les opcions et duran al menú següent. Prem Esc per a aturar-ho." explanation="" max="38*6"/>
<string english="cutscene test" translation="" explanation="menu option"/>
<string english="Cutscene test" translation="" explanation="title" max="20"/>
<string english="Display all text boxes from cutscenes.xml. Only tests the basic appearance of each individual text box." translation="" explanation="" max="38*6"/>
<string english="from clipboard" translation="" explanation="menu option, paste script name from clipboard"/>
<string english="explore game" translation="explora el joc" explanation="menu option"/>
<string english="Explore game" translation="Explora el joc" explanation="title" max="20"/>
<string english="Explore the rooms of any level in the game, to find all room names to translate." translation="Explora les sales de qualsevol nivell del joc per a trobar tots els noms|de sales i traduir-los." explanation="" max="38*6"/>
@ -544,8 +548,6 @@
<string english="ENEMY BOUNDS: Click on bottom right" translation="LÍMITS DENEMIC:|Fes clic a la part inferior dreta" explanation="editor, invisible box which enemies always stay inside of" max="39*3"/>
<string english="PLATFORM BOUNDS: Click on top left" translation="LÍMITS DE PLATAFORMA:|Fes clic a la part superior esquerra" explanation="editor, invisible box which moving platforms always stay inside of" max="39*3"/>
<string english="PLATFORM BOUNDS: Click on bottom right" translation="LÍMITS DE PLATAFORMA:|Fes clic a la part inferior dreta" explanation="editor, invisible box which moving platforms always stay inside of" max="39*3"/>
<string english="COPY TILES: Click on top left" translation="COPIA PECES:|Fes clic a la part superior esquerra" explanation="" max="39*3"/>
<string english="COPY TILES: Click on bottom right" translation="COPIA PECES:|Fes clic a la part inferior dreta" explanation="" max="39*3"/>
<string english="Click on top left" translation="Fes clic a la part superior esquerra" explanation="" max="39*3"/>
<string english="Click on bottom right" translation="Fes clic a la part inferior dreta" explanation="" max="39*3"/>
<string english="**** VVVVVV SCRIPT EDITOR ****" translation="*** EDITOR DE SCRIPTS DE VVVVVV ***" explanation="supposed to look like a Commodore 64 screen" max="36"/>

View File

@ -165,6 +165,10 @@
<string english="menu test" translation="" explanation="menu option"/>
<string english="Menu test" translation="" explanation="title" max="20"/>
<string english="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." translation="" explanation="" max="38*6"/>
<string english="cutscene test" translation="" explanation="menu option"/>
<string english="Cutscene test" translation="" explanation="title" max="20"/>
<string english="Display all text boxes from cutscenes.xml. Only tests the basic appearance of each individual text box." translation="" explanation="" max="38*6"/>
<string english="from clipboard" translation="" explanation="menu option, paste script name from clipboard"/>
<string english="explore game" translation="" explanation="menu option"/>
<string english="Explore game" translation="" explanation="title" max="20"/>
<string english="Explore the rooms of any level in the game, to find all room names to translate." translation="" explanation="" max="38*6"/>

View File

@ -165,6 +165,10 @@
<string english="menu test" translation="menu-testado" explanation="menu option"/>
<string english="Menu test" translation="Menu-testado" explanation="title" max="20"/>
<string english="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." translation="Cikli tra la plejparto da menuoj en la ludo. La menuoj ne vere funkcios; ĉiuj elektoj anstataŭe prenos vin al sekva menuo. Premu eskapklavon por fini." explanation="" max="38*6"/>
<string english="cutscene test" translation="" explanation="menu option"/>
<string english="Cutscene test" translation="" explanation="title" max="20"/>
<string english="Display all text boxes from cutscenes.xml. Only tests the basic appearance of each individual text box." translation="" explanation="" max="38*6"/>
<string english="from clipboard" translation="" explanation="menu option, paste script name from clipboard"/>
<string english="explore game" translation="esplori ludon" explanation="menu option"/>
<string english="Explore game" translation="Esplori ludon" explanation="title" max="20"/>
<string english="Explore the rooms of any level in the game, to find all room names to translate." translation="Esplori la ĉambrojn de iu ajn nivelo en la ludo, por trovi ĉiujn tradukendajn ĉambronomojn." explanation="" max="38*6"/>

View File

@ -165,6 +165,10 @@
<string english="menu test" translation="" explanation="menu option"/>
<string english="Menu test" translation="" explanation="title" max="20"/>
<string english="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." translation="" explanation="" max="38*6"/>
<string english="cutscene test" translation="" explanation="menu option"/>
<string english="Cutscene test" translation="" explanation="title" max="20"/>
<string english="Display all text boxes from cutscenes.xml. Only tests the basic appearance of each individual text box." translation="" explanation="" max="38*6"/>
<string english="from clipboard" translation="" explanation="menu option, paste script name from clipboard"/>
<string english="explore game" translation="" explanation="menu option"/>
<string english="Explore game" translation="" explanation="title" max="20"/>
<string english="Explore the rooms of any level in the game, to find all room names to translate." translation="" explanation="" max="38*6"/>

View File

@ -165,6 +165,10 @@
<string english="menu test" translation="menutest" explanation="menu option"/>
<string english="Menu test" translation="Menutest" explanation="title" max="20"/>
<string english="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." translation="De meeste menu&apos;s in het spel doorlopen. De menu&apos;s zullen niet echt werken, alle opties zullen in plaats daarvan naar het volgende menu leiden. Druk op Escape om te stoppen." explanation="" max="38*6"/>
<string english="cutscene test" translation="cutscene-test" explanation="menu option"/>
<string english="Cutscene test" translation="Cutscene-test" explanation="title" max="20"/>
<string english="Display all text boxes from cutscenes.xml. Only tests the basic appearance of each individual text box." translation="Toon alle tekstvakken uit cutscenes.xml. Alleen de basale weergave van elk afzonderlijk tekstvak wordt getest." explanation="" max="38*6"/>
<string english="from clipboard" translation="van klembord" explanation="menu option, paste script name from clipboard"/>
<string english="explore game" translation="spel verkennen" explanation="menu option"/>
<string english="Explore game" translation="Spel verkennen" explanation="title" max="20"/>
<string english="Explore the rooms of any level in the game, to find all room names to translate." translation="Verken de kamers van elk level in het spel, om alle kamers te vinden die vertaald kunnen worden." explanation="" max="38*6"/>

View File

@ -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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -21,6 +21,7 @@ std::vector<LangMeta> languagelist;
int languagelist_curlang;
bool show_translator_menu = false;
size_t limitscheck_current_overflow;
std::vector<std::string> testable_script_ids;
int n_untranslated_roomnames = 0;
int n_unexplained_roomnames = 0;

View File

@ -52,6 +52,7 @@ extern std::vector<LangMeta> languagelist;
extern int languagelist_curlang;
extern bool show_translator_menu;
extern size_t limitscheck_current_overflow;
extern std::vector<std::string> testable_script_ids;
extern int n_untranslated_roomnames;
extern int n_unexplained_roomnames;

View File

@ -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 */

View File

@ -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 */

View File

@ -2,8 +2,6 @@
#include "Localization.h"
#include "LocalizationStorage.h"
#include <tinyxml2.h>
#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

View File

@ -1,6 +1,8 @@
#ifndef LOCALIZATIONSTORAGE_H
#define LOCALIZATIONSTORAGE_H
#include <tinyxml2.h>
#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);

View File

@ -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;

View File

@ -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)");
}

View File

@ -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);