From 8d5e3b1a8a1bafbd8142c65754f841c37808139d Mon Sep 17 00:00:00 2001 From: Dav999-v Date: Thu, 19 Jan 2023 20:15:17 +0100 Subject: [PATCH] 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. --- desktop_version/src/CustomLevels.cpp | 20 ++++-- desktop_version/src/CustomLevels.h | 9 ++- desktop_version/src/Editor.cpp | 99 +++++++++++++++++++++------- desktop_version/src/Game.cpp | 2 +- desktop_version/src/Render.cpp | 39 +++++++---- 5 files changed, 122 insertions(+), 47 deletions(-) diff --git a/desktop_version/src/CustomLevels.cpp b/desktop_version/src/CustomLevels.cpp index 2fbb7f62..6157f6f2 100644 --- a/desktop_version/src/CustomLevels.cpp +++ b/desktop_version/src/CustomLevels.cpp @@ -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. * This way we translate "Untitled Level" and "Unknown" without * 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") + { + *is_gettext = true; return loc::gettext("Untitled Level"); + } + *is_gettext = false; return title; } -std::string translate_creator(const std::string& creator) +std::string translate_creator(const std::string& creator, bool* is_gettext) { if (creator == "Unknown") + { + *is_gettext = true; return loc::gettext("Unknown"); + } + *is_gettext = false; return creator; } @@ -250,9 +258,6 @@ static void levelMetaDataCallback(const char* filename) if (cl.getLevelMetaData(filename_, temp)) { - temp.title = translate_title(temp.title); - temp.creator = translate_creator(temp.creator); - cl.ListOfMetaData.push_back(temp); } } @@ -301,13 +306,14 @@ bool customlevelclass::getLevelMetaDataAndPlaytestArgs(const std::string& _path, return false; } - _data.creator = find_creator(buf); - _data.title = find_title(buf); + _data.creator = translate_creator(find_creator(buf), &_data.creator_is_gettext); + _data.title = translate_title(find_title(buf), &_data.title_is_gettext); _data.Desc1 = find_desc1(buf); _data.Desc2 = find_desc2(buf); _data.Desc3 = find_desc3(buf); _data.website = find_website(buf); + if (pt_args != NULL) { const std::string playtest = find_playtest(buf); diff --git a/desktop_version/src/CustomLevels.h b/desktop_version/src/CustomLevels.h index 8ce02e93..da553b78 100644 --- a/desktop_version/src/CustomLevels.h +++ b/desktop_version/src/CustomLevels.h @@ -58,6 +58,11 @@ struct LevelMetaData std::string timeModified; 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 @@ -160,9 +165,9 @@ public: 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 extern customlevelclass cl; diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index bab3646c..6aa0cb67 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -319,9 +319,9 @@ static void editormenurender(int tr, int tg, int tb) if (game.currentmenuoption == 3) { 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 - 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; case Menu::ed_desc: @@ -330,17 +330,20 @@ static void editormenurender(int tr, int tg, int tb) { 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 { - 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 { - 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; if(ed.creatormod) { @@ -355,7 +358,7 @@ static void editormenurender(int tr, int tg, int tb) } else { - creator = translate_creator(cl.creator); + creator = translate_creator(cl.creator, &creator_is_gettext); } char creatorline[SCREEN_WIDTH_CHARS + 1]; vformat_buf( @@ -364,67 +367,68 @@ static void editormenurender(int tr, int tg, int tb) "author: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.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 { - 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 { - 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.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 { - 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 { - 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.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 { - 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 { - 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.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 { - 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; } @@ -1817,15 +1821,37 @@ static void editormenuactionpress(void) switch (game.currentmenuoption) { case 0: + { + bool title_is_gettext; + translate_title(cl.title, &title_is_gettext); ed.titlemod=true; key.enabletextentry(); - key.keybuffer=translate_title(cl.title); + if (title_is_gettext) + { + key.keybuffer=""; + } + else + { + key.keybuffer = cl.title; + } break; + } case 1: + { + bool creator_is_gettext; + translate_creator(cl.creator, &creator_is_gettext); ed.creatormod=true; key.enabletextentry(); - key.keybuffer=translate_creator(cl.creator); + if (creator_is_gettext) + { + key.keybuffer=""; + } + else + { + key.keybuffer = cl.creator; + } break; + } case 2: ed.desc1mod=true; key.enabletextentry(); @@ -2440,10 +2466,18 @@ void editorinput(void) if(ed.titlemod) { cl.title=key.keybuffer; + if (cl.title == "") + { + cl.title = "Untitled Level"; + } } else if(ed.creatormod) { cl.creator=key.keybuffer; + if (cl.creator == "") + { + cl.creator = "Unknown"; + } } else if(ed.websitemod) { @@ -2471,11 +2505,19 @@ void editorinput(void) if(ed.titlemod) { cl.title=key.keybuffer; + if (cl.title == "") + { + cl.title = "Untitled Level"; + } ed.titlemod=false; } else if(ed.creatormod) { cl.creator=key.keybuffer; + if (cl.creator == "") + { + cl.creator = "Unknown"; + } ed.creatormod=false; } else if(ed.websitemod) @@ -2510,9 +2552,16 @@ void editorinput(void) { ed.desc2mod=false; - ed.desc3mod=true; - key.enabletextentry(); - key.keybuffer=cl.Desc3; + if (font::height(PR_FONT_LEVEL) <= 10) + { + ed.desc3mod=true; + key.enabletextentry(); + key.keybuffer=cl.Desc3; + } + else + { + cl.Desc3=""; + } } music.playef(11); } diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index 27328464..3f958b16 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -6266,7 +6266,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) { 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) diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index aef7b792..08df1645 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -198,7 +198,11 @@ static void menurender(void) }else{ // 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]; vformat_buf( creatorline, sizeof(creatorline), @@ -206,11 +210,15 @@ static void menurender(void) "author:str", cl.ListOfMetaData[tmp].creator.c_str() ); - graphics.Print( -1, 40, creatorline, tr, tg, tb, true); - graphics.Print( -1, 50, cl.ListOfMetaData[tmp].website, tr, tg, tb, true); - graphics.Print( -1, 70, cl.ListOfMetaData[tmp].Desc1, tr, tg, tb, true); - graphics.Print( -1, 80, cl.ListOfMetaData[tmp].Desc2, tr, tg, tb, true); - graphics.Print( -1, 90, cl.ListOfMetaData[tmp].Desc3, tr, tg, tb, true); + int sp = SDL_max(10, font::height(level_flags)); + font::print(creator_flags | PR_CEN, -1, 40, creatorline, tr, tg, tb); + font::print(level_flags | PR_CEN, -1, 40+sp, cl.ListOfMetaData[tmp].website, tr, tg, tb); + font::print(level_flags | PR_CEN, -1, 40+sp*3, cl.ListOfMetaData[tmp].Desc1, tr, tg, tb); + 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; @@ -2588,7 +2596,10 @@ void maprender(void) else if(map.custommode){ 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]; vformat_buf( buffer, sizeof(buffer), @@ -2596,11 +2607,15 @@ void maprender(void) "author:str", meta.creator.c_str() ); - font::print(PR_CEN | PR_FONT_LEVEL, -1, FLIP(70, 8), buffer, 196, 196, 255 - help.glow); - font::print(PR_CEN | PR_FONT_LEVEL, -1, FLIP(80, 8), meta.website, 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_CEN | PR_FONT_LEVEL, -1, FLIP(110, 8), meta.Desc2, 196, 196, 255 - help.glow); - font::print(PR_CEN | PR_FONT_LEVEL, -1, FLIP(120, 8), meta.Desc3, 196, 196, 255 - help.glow); + int sp = SDL_max(10, font::height(PR_FONT_LEVEL)); + font::print(creator_flags | PR_CEN, -1, FLIP(70, 8), buffer, 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_FONT_LEVEL | PR_CEN, -1, FLIP(70+sp*3, 8), meta.Desc1, 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();