1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-30 16:38:29 +02:00

Improve level metadata display and font handling

- If the level font is higher than 10 pixels, the third description
  line (Desc3) is disabled and unavailable. CJK languages require less
  characters to convey the same message (140 characters caused people
  to cram tweets in all languages except CJK) and this gives us enough
  room in the levels list without having to cram the metadata even more
  than it already was or showing less levels per page.
- The "Untitled Level" and "by Unknown" now selectively show up in the
  interface font instead of the level font.
This commit is contained in:
Dav999-v 2023-01-19 20:15:17 +01:00 committed by Misa Elizabeth Kai
parent 653eee505b
commit 8d5e3b1a8a
5 changed files with 122 additions and 47 deletions

View File

@ -89,17 +89,25 @@ static bool compare_nocase (std::string first, std::string second)
* as being translated, while they're actually stored in English in the level file. * as being translated, while they're actually stored in English in the level file.
* This way we translate "Untitled Level" and "Unknown" without * This way we translate "Untitled Level" and "Unknown" without
* spreading around translations in level files posted online! */ * spreading around translations in level files posted online! */
std::string translate_title(const std::string& title) std::string translate_title(const std::string& title, bool* is_gettext)
{ {
if (title == "Untitled Level") if (title == "Untitled Level")
{
*is_gettext = true;
return loc::gettext("Untitled Level"); return loc::gettext("Untitled Level");
}
*is_gettext = false;
return title; return title;
} }
std::string translate_creator(const std::string& creator) std::string translate_creator(const std::string& creator, bool* is_gettext)
{ {
if (creator == "Unknown") if (creator == "Unknown")
{
*is_gettext = true;
return loc::gettext("Unknown"); return loc::gettext("Unknown");
}
*is_gettext = false;
return creator; return creator;
} }
@ -250,9 +258,6 @@ static void levelMetaDataCallback(const char* filename)
if (cl.getLevelMetaData(filename_, temp)) if (cl.getLevelMetaData(filename_, temp))
{ {
temp.title = translate_title(temp.title);
temp.creator = translate_creator(temp.creator);
cl.ListOfMetaData.push_back(temp); cl.ListOfMetaData.push_back(temp);
} }
} }
@ -301,13 +306,14 @@ bool customlevelclass::getLevelMetaDataAndPlaytestArgs(const std::string& _path,
return false; return false;
} }
_data.creator = find_creator(buf); _data.creator = translate_creator(find_creator(buf), &_data.creator_is_gettext);
_data.title = find_title(buf); _data.title = translate_title(find_title(buf), &_data.title_is_gettext);
_data.Desc1 = find_desc1(buf); _data.Desc1 = find_desc1(buf);
_data.Desc2 = find_desc2(buf); _data.Desc2 = find_desc2(buf);
_data.Desc3 = find_desc3(buf); _data.Desc3 = find_desc3(buf);
_data.website = find_website(buf); _data.website = find_website(buf);
if (pt_args != NULL) if (pt_args != NULL)
{ {
const std::string playtest = find_playtest(buf); const std::string playtest = find_playtest(buf);

View File

@ -58,6 +58,11 @@ struct LevelMetaData
std::string timeModified; std::string timeModified;
int version; int version;
/* true if a system "Untitled Level"/"Unknown"
* was stored in this struct (for the levels list) */
bool title_is_gettext;
bool creator_is_gettext;
}; };
struct CliPlaytestArgs struct CliPlaytestArgs
@ -160,9 +165,9 @@ public:
bool onewaycol_override; bool onewaycol_override;
}; };
std::string translate_title(const std::string& title); std::string translate_title(const std::string& title, bool* is_gettext);
std::string translate_creator(const std::string& creator); std::string translate_creator(const std::string& creator, bool* is_gettext);
#ifndef CL_DEFINITION #ifndef CL_DEFINITION
extern customlevelclass cl; extern customlevelclass cl;

View File

@ -319,9 +319,9 @@ static void editormenurender(int tr, int tg, int tb)
if (game.currentmenuoption == 3) if (game.currentmenuoption == 3)
{ {
if (!game.ghostsenabled) if (!game.ghostsenabled)
graphics.Print(2, 230, loc::gettext("Editor ghost trail is OFF"), tr/2, tg/2, tb/2); font::print(0, 2, 230, loc::gettext("Editor ghost trail is OFF"), tr/2, tg/2, tb/2);
else else
graphics.Print(2, 230, loc::gettext("Editor ghost trail is ON"), tr, tg, tb); font::print(0, 2, 230, loc::gettext("Editor ghost trail is ON"), tr, tg, tb);
} }
break; break;
case Menu::ed_desc: case Menu::ed_desc:
@ -330,17 +330,20 @@ static void editormenurender(int tr, int tg, int tb)
{ {
if(ed.entframe<2) if(ed.entframe<2)
{ {
font::print(PR_2X | PR_CEN, -1, 35, key.keybuffer+"_", tr, tg, tb); font::print(PR_2X | PR_CEN | PR_FONT_LEVEL, -1, 35, key.keybuffer+"_", tr, tg, tb);
} }
else else
{ {
font::print(PR_2X | PR_CEN, -1, 35, key.keybuffer+" ", tr, tg, tb); font::print(PR_2X | PR_CEN | PR_FONT_LEVEL, -1, 35, key.keybuffer+" ", tr, tg, tb);
} }
} }
else else
{ {
font::print(PR_2X | PR_CEN, -1, 35, translate_title(cl.title), tr, tg, tb); bool title_is_gettext;
std::string title = translate_title(cl.title, &title_is_gettext);
font::print(PR_2X | PR_CEN | (title_is_gettext ? PR_FONT_INTERFACE : PR_FONT_LEVEL), -1, 35, title, tr, tg, tb);
} }
bool creator_is_gettext = false;
std::string creator; std::string creator;
if(ed.creatormod) if(ed.creatormod)
{ {
@ -355,7 +358,7 @@ static void editormenurender(int tr, int tg, int tb)
} }
else else
{ {
creator = translate_creator(cl.creator); creator = translate_creator(cl.creator, &creator_is_gettext);
} }
char creatorline[SCREEN_WIDTH_CHARS + 1]; char creatorline[SCREEN_WIDTH_CHARS + 1];
vformat_buf( vformat_buf(
@ -364,67 +367,68 @@ static void editormenurender(int tr, int tg, int tb)
"author:str", "author:str",
creator.c_str() creator.c_str()
); );
graphics.Print( -1, 60, creatorline, tr, tg, tb, true); int sp = SDL_max(10, font::height(PR_FONT_LEVEL));
font::print(PR_CEN | (creator_is_gettext ? PR_FONT_INTERFACE : PR_FONT_LEVEL), -1, 60, creatorline, tr, tg, tb);
if(ed.websitemod) if(ed.websitemod)
{ {
if(ed.entframe<2) if(ed.entframe<2)
{ {
graphics.Print( -1, 70, key.keybuffer+"_", tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp, key.keybuffer+"_", tr, tg, tb);
} }
else else
{ {
graphics.Print( -1, 70, key.keybuffer+" ", tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp, key.keybuffer+" ", tr, tg, tb);
} }
} }
else else
{ {
graphics.Print( -1, 70, cl.website, tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp, cl.website, tr, tg, tb);
} }
if(ed.desc1mod) if(ed.desc1mod)
{ {
if(ed.entframe<2) if(ed.entframe<2)
{ {
graphics.Print( -1, 90, key.keybuffer+"_", tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*3, key.keybuffer+"_", tr, tg, tb);
} }
else else
{ {
graphics.Print( -1, 90, key.keybuffer+" ", tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*3, key.keybuffer+" ", tr, tg, tb);
} }
} }
else else
{ {
graphics.Print( -1, 90, cl.Desc1, tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*3, cl.Desc1, tr, tg, tb);
} }
if(ed.desc2mod) if(ed.desc2mod)
{ {
if(ed.entframe<2) if(ed.entframe<2)
{ {
graphics.Print( -1, 100, key.keybuffer+"_", tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*4, key.keybuffer+"_", tr, tg, tb);
} }
else else
{ {
graphics.Print( -1, 100, key.keybuffer+" ", tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*4, key.keybuffer+" ", tr, tg, tb);
} }
} }
else else
{ {
graphics.Print( -1, 100, cl.Desc2, tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*4, cl.Desc2, tr, tg, tb);
} }
if(ed.desc3mod) if(ed.desc3mod)
{ {
if(ed.entframe<2) if(ed.entframe<2)
{ {
graphics.Print( -1, 110, key.keybuffer+"_", tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*5, key.keybuffer+"_", tr, tg, tb);
} }
else else
{ {
graphics.Print( -1, 110, key.keybuffer+" ", tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*5, key.keybuffer+" ", tr, tg, tb);
} }
} }
else else if (sp <= 10)
{ {
graphics.Print( -1, 110, cl.Desc3, tr, tg, tb, true); font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*5, cl.Desc3, tr, tg, tb);
} }
break; break;
} }
@ -1817,15 +1821,37 @@ static void editormenuactionpress(void)
switch (game.currentmenuoption) switch (game.currentmenuoption)
{ {
case 0: case 0:
{
bool title_is_gettext;
translate_title(cl.title, &title_is_gettext);
ed.titlemod=true; ed.titlemod=true;
key.enabletextentry(); key.enabletextentry();
key.keybuffer=translate_title(cl.title); if (title_is_gettext)
{
key.keybuffer="";
}
else
{
key.keybuffer = cl.title;
}
break; break;
}
case 1: case 1:
{
bool creator_is_gettext;
translate_creator(cl.creator, &creator_is_gettext);
ed.creatormod=true; ed.creatormod=true;
key.enabletextentry(); key.enabletextentry();
key.keybuffer=translate_creator(cl.creator); if (creator_is_gettext)
{
key.keybuffer="";
}
else
{
key.keybuffer = cl.creator;
}
break; break;
}
case 2: case 2:
ed.desc1mod=true; ed.desc1mod=true;
key.enabletextentry(); key.enabletextentry();
@ -2440,10 +2466,18 @@ void editorinput(void)
if(ed.titlemod) if(ed.titlemod)
{ {
cl.title=key.keybuffer; cl.title=key.keybuffer;
if (cl.title == "")
{
cl.title = "Untitled Level";
}
} }
else if(ed.creatormod) else if(ed.creatormod)
{ {
cl.creator=key.keybuffer; cl.creator=key.keybuffer;
if (cl.creator == "")
{
cl.creator = "Unknown";
}
} }
else if(ed.websitemod) else if(ed.websitemod)
{ {
@ -2471,11 +2505,19 @@ void editorinput(void)
if(ed.titlemod) if(ed.titlemod)
{ {
cl.title=key.keybuffer; cl.title=key.keybuffer;
if (cl.title == "")
{
cl.title = "Untitled Level";
}
ed.titlemod=false; ed.titlemod=false;
} }
else if(ed.creatormod) else if(ed.creatormod)
{ {
cl.creator=key.keybuffer; cl.creator=key.keybuffer;
if (cl.creator == "")
{
cl.creator = "Unknown";
}
ed.creatormod=false; ed.creatormod=false;
} }
else if(ed.websitemod) else if(ed.websitemod)
@ -2510,10 +2552,17 @@ void editorinput(void)
{ {
ed.desc2mod=false; ed.desc2mod=false;
if (font::height(PR_FONT_LEVEL) <= 10)
{
ed.desc3mod=true; ed.desc3mod=true;
key.enabletextentry(); key.enabletextentry();
key.keybuffer=cl.Desc3; key.keybuffer=cl.Desc3;
} }
else
{
cl.Desc3="";
}
}
music.playef(11); music.playef(11);
} }
} }

View File

@ -6266,7 +6266,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ )
{ {
text[ii] = SDL_tolower(text[ii]); text[ii] = SDL_tolower(text[ii]);
} }
option(text); option(text, true, cl.ListOfMetaData[i].title_is_gettext ? PR_FONT_INTERFACE : PR_FONT_8X8); // TODO level font
} }
} }
if (cl.ListOfMetaData.size() > 8) if (cl.ListOfMetaData.size() > 8)

View File

@ -198,7 +198,11 @@ static void menurender(void)
}else{ }else{
// TODO: Use level-specific font (via PR_FONT_IDX?) // TODO: Use level-specific font (via PR_FONT_IDX?)
font::print(PR_2X | PR_CEN, -1, 15, cl.ListOfMetaData[tmp].title, tr, tg, tb); uint32_t level_flags = PR_FONT_8X8; // TEMP
uint32_t title_flags = cl.ListOfMetaData[tmp].title_is_gettext ? PR_FONT_INTERFACE : level_flags;
uint32_t creator_flags = cl.ListOfMetaData[tmp].creator_is_gettext ? PR_FONT_INTERFACE : level_flags;
font::print(title_flags | PR_2X | PR_CEN, -1, 15, cl.ListOfMetaData[tmp].title, tr, tg, tb);
char creatorline[SCREEN_WIDTH_CHARS + 1]; char creatorline[SCREEN_WIDTH_CHARS + 1];
vformat_buf( vformat_buf(
creatorline, sizeof(creatorline), creatorline, sizeof(creatorline),
@ -206,11 +210,15 @@ static void menurender(void)
"author:str", "author:str",
cl.ListOfMetaData[tmp].creator.c_str() cl.ListOfMetaData[tmp].creator.c_str()
); );
graphics.Print( -1, 40, creatorline, tr, tg, tb, true); int sp = SDL_max(10, font::height(level_flags));
graphics.Print( -1, 50, cl.ListOfMetaData[tmp].website, tr, tg, tb, true); font::print(creator_flags | PR_CEN, -1, 40, creatorline, tr, tg, tb);
graphics.Print( -1, 70, cl.ListOfMetaData[tmp].Desc1, tr, tg, tb, true); font::print(level_flags | PR_CEN, -1, 40+sp, cl.ListOfMetaData[tmp].website, tr, tg, tb);
graphics.Print( -1, 80, cl.ListOfMetaData[tmp].Desc2, tr, tg, tb, true); font::print(level_flags | PR_CEN, -1, 40+sp*3, cl.ListOfMetaData[tmp].Desc1, tr, tg, tb);
graphics.Print( -1, 90, cl.ListOfMetaData[tmp].Desc3, tr, tg, tb, true); font::print(level_flags | PR_CEN, -1, 40+sp*4, cl.ListOfMetaData[tmp].Desc2, tr, tg, tb);
if (sp <= 10)
{
font::print(level_flags | PR_CEN, -1, 40+sp*5, cl.ListOfMetaData[tmp].Desc3, tr, tg, tb);
}
} }
} }
break; break;
@ -2588,7 +2596,10 @@ void maprender(void)
else if(map.custommode){ else if(map.custommode){
LevelMetaData& meta = cl.ListOfMetaData[game.playcustomlevel]; LevelMetaData& meta = cl.ListOfMetaData[game.playcustomlevel];
font::print(PR_2X | PR_CEN | PR_FONT_LEVEL, -1, FLIP(45, 8), meta.title, 196, 196, 255 - help.glow); uint32_t title_flags = meta.title_is_gettext ? PR_FONT_INTERFACE : PR_FONT_LEVEL;
uint32_t creator_flags = meta.creator_is_gettext ? PR_FONT_INTERFACE : PR_FONT_LEVEL;
font::print(title_flags | PR_2X | PR_CEN, -1, FLIP(45, 8), meta.title, 196, 196, 255 - help.glow);
char buffer[SCREEN_WIDTH_CHARS + 1]; char buffer[SCREEN_WIDTH_CHARS + 1];
vformat_buf( vformat_buf(
buffer, sizeof(buffer), buffer, sizeof(buffer),
@ -2596,11 +2607,15 @@ void maprender(void)
"author:str", "author:str",
meta.creator.c_str() meta.creator.c_str()
); );
font::print(PR_CEN | PR_FONT_LEVEL, -1, FLIP(70, 8), buffer, 196, 196, 255 - help.glow); int sp = SDL_max(10, font::height(PR_FONT_LEVEL));
font::print(PR_CEN | PR_FONT_LEVEL, -1, FLIP(80, 8), meta.website, 196, 196, 255 - help.glow); font::print(creator_flags | PR_CEN, -1, FLIP(70, 8), buffer, 196, 196, 255 - help.glow);
font::print(PR_CEN | PR_FONT_LEVEL, -1, FLIP(100, 8), meta.Desc1, 196, 196, 255 - help.glow); font::print(PR_FONT_LEVEL | PR_CEN, -1, FLIP(70+sp, 8), meta.website, 196, 196, 255 - help.glow);
font::print(PR_CEN | PR_FONT_LEVEL, -1, FLIP(110, 8), meta.Desc2, 196, 196, 255 - help.glow); font::print(PR_FONT_LEVEL | PR_CEN, -1, FLIP(70+sp*3, 8), meta.Desc1, 196, 196, 255 - help.glow);
font::print(PR_CEN | PR_FONT_LEVEL, -1, FLIP(120, 8), meta.Desc3, 196, 196, 255 - help.glow); font::print(PR_FONT_LEVEL | PR_CEN, -1, FLIP(70+sp*4, 8), meta.Desc2, 196, 196, 255 - help.glow);
if (sp <= 10)
{
font::print(PR_FONT_LEVEL | PR_CEN, -1, FLIP(70+sp*5, 8), meta.Desc3, 196, 196, 255 - help.glow);
}
int remaining = cl.numcrewmates() - game.crewmates(); int remaining = cl.numcrewmates() - game.crewmates();