diff --git a/desktop_version/fonts/font.fontmeta b/desktop_version/fonts/font.fontmeta index b28d3a1c..f842fe7a 100644 --- a/desktop_version/fonts/font.fontmeta +++ b/desktop_version/fonts/font.fontmeta @@ -1,5 +1,6 @@ + english/… 8 8 1 diff --git a/desktop_version/lang/ca/strings.xml b/desktop_version/lang/ca/strings.xml index fad38db8..ae9df606 100644 --- a/desktop_version/lang/ca/strings.xml +++ b/desktop_version/lang/ca/strings.xml @@ -513,6 +513,10 @@ + + + + diff --git a/desktop_version/lang/en/strings.xml b/desktop_version/lang/en/strings.xml index b9e5e38e..6e2611f0 100644 --- a/desktop_version/lang/en/strings.xml +++ b/desktop_version/lang/en/strings.xml @@ -513,6 +513,10 @@ + + + + diff --git a/desktop_version/lang/eo/strings.xml b/desktop_version/lang/eo/strings.xml index 9577ba9c..81f0e0d8 100644 --- a/desktop_version/lang/eo/strings.xml +++ b/desktop_version/lang/eo/strings.xml @@ -513,6 +513,10 @@ + + + + diff --git a/desktop_version/lang/es/strings.xml b/desktop_version/lang/es/strings.xml index 03d53eb9..e5806044 100644 --- a/desktop_version/lang/es/strings.xml +++ b/desktop_version/lang/es/strings.xml @@ -513,6 +513,10 @@ + + + + diff --git a/desktop_version/lang/nl/strings.xml b/desktop_version/lang/nl/strings.xml index 4299be01..f4e6891b 100644 --- a/desktop_version/lang/nl/strings.xml +++ b/desktop_version/lang/nl/strings.xml @@ -513,6 +513,10 @@ + + + + diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index 3f3a3e43..1ba745ca 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -430,6 +430,14 @@ static void editormenurender(int tr, int tg, int tb) { font::print(PR_CEN | PR_FONT_LEVEL, -1, 60+sp*5, cl.Desc3, tr, tg, tb); } + + const char* label = loc::gettext("Font: "); + int len_label = font::len(0, label); + const char* name = font::get_level_font_display_name(); + + font::print(0, 2, 230, label, tr/2, tg/2, tb/2); + font::print(PR_FONT_LEVEL, 2+len_label, 230, name, tr/2, tg/2, tb/2); + break; } case Menu::ed_music: @@ -498,6 +506,19 @@ static void editormenurender(int tr, int tg, int tb) case Menu::ed_quit: font::print_wrap(PR_CEN, -1, 90, loc::gettext("Save before quitting?"), tr, tg, tb); break; + case Menu::ed_font: + { + font::print(PR_2X | PR_CEN, -1, 30, loc::gettext("Level Font"), tr, tg, tb); + font::print_wrap(PR_CEN, -1, 65, loc::gettext("Select the language in which the text in this level is written."), tr, tg, tb); + + const char* label = loc::gettext("Font: "); + int len_label = font::len(0, label); + const char* name = font::get_level_font_display_name(); + + font::print(0, 2, 230, label, tr/2, tg/2, tb/2); + font::print(PR_FONT_LEVEL, 2+len_label, 230, name, tr/2, tg/2, tb/2); + break; + } default: break; } @@ -1864,6 +1885,10 @@ static void editormenuactionpress(void) key.keybuffer=cl.website; break; case 4: + game.createmenu(Menu::ed_font); + map.nexttowercolour(); + break; + case 5: game.returnmenu(); map.nexttowercolour(); break; @@ -2003,6 +2028,25 @@ static void editormenuactionpress(void) break; } break; + case Menu::ed_font: + { + uint8_t idx_selected = font::font_idx_options[game.currentmenuoption]; + cl.level_font_name = font::get_main_font_name(idx_selected); + if (idx_selected == loc::get_langmeta()->font_idx) + { + loc::new_level_font = ""; + } + else + { + loc::new_level_font = cl.level_font_name; + } + font::set_level_font(cl.level_font_name.c_str()); + music.playef(11); + game.returnmenu(); + map.nexttowercolour(); + game.savestatsandsettings_menu(); + break; + } default: break; } @@ -2099,7 +2143,7 @@ void editorinput(void) } else { - + bool esc_from_font = false; music.playef(11); if (ed.settingsmod) { @@ -2113,6 +2157,13 @@ void editorinput(void) { ed.settingsmod = false; } + else if (game.currentmenuname == Menu::ed_font) + { + // Prevent double return + esc_from_font = true; + game.returnmenu(); + map.nexttowercolour(); + } else { game.returnmenu(); @@ -2125,7 +2176,7 @@ void editorinput(void) ed.settingsmod = true; } - if (ed.settingsmod) + if (ed.settingsmod && !esc_from_font) { bool edsettings_in_stack = game.currentmenuname == Menu::ed_settings; if (!edsettings_in_stack) diff --git a/desktop_version/src/Font.cpp b/desktop_version/src/Font.cpp index 1c4173f8..7fb9a1a6 100644 --- a/desktop_version/src/Font.cpp +++ b/desktop_version/src/Font.cpp @@ -5,6 +5,7 @@ #include "Alloc.h" #include "Constants.h" +#include "CustomLevels.h" #include "FileSystemUtils.h" #include "Graphics.h" #include "GraphicsUtil.h" @@ -37,6 +38,7 @@ struct GlyphInfo struct Font { char name[64]; + char display_name[SCREEN_WIDTH_CHARS + 1]; uint8_t glyph_w; uint8_t glyph_h; @@ -70,6 +72,9 @@ static FontContainer fonts_custom = {}; static uint8_t font_idx_8x8 = 0; +uint8_t font_idx_options_n = 0; +uint8_t font_idx_options[20]; + static bool font_level_is_interface = false; static bool font_idx_level_is_custom = false; static uint8_t font_idx_level = 0; @@ -218,6 +223,7 @@ static uint8_t load_font(FontContainer* container, const char* name) SDL_snprintf(name_txt, sizeof(name_txt), "graphics/%s.txt", name); SDL_snprintf(name_xml, sizeof(name_xml), "graphics/%s.fontmeta", name); SDL_strlcpy(f->name, name, sizeof(f->name)); + SDL_strlcpy(f->display_name, name, sizeof(f->display_name)); f->glyph_w = 8; f->glyph_h = 8; @@ -236,6 +242,10 @@ static uint8_t load_font(FontContainer* container, const char* name) xml_loaded = true; hDoc = hDoc.FirstChildElement("font_metadata"); + if ((pElem = hDoc.FirstChildElement("display_name").ToElement()) != NULL) + { + SDL_strlcpy(f->display_name, pElem->GetText(), sizeof(f->display_name)); + } if ((pElem = hDoc.FirstChildElement("width").ToElement()) != NULL) { f->glyph_w = help.Int(pElem->GetText()); @@ -405,6 +415,11 @@ uint8_t get_font_idx_8x8(void) return font_idx_8x8; } +bool level_font_is_main_idx(const uint8_t idx) +{ + return !font_idx_level_is_custom && font_idx_level == idx; +} + void set_level_font(const char* name) { /* Apply the choice for a certain level-specific font. @@ -439,6 +454,33 @@ void set_level_font_interface(void) font_level_is_interface = true; } +void set_level_font_new(void) +{ + /* Set the level font to the default font for new levels. + * This function is for starting the editor. */ + font_level_is_interface = false; + font_idx_level_is_custom = false; + if (loc::new_level_font == "") + { + /* Just take the language's font + * (Japanese VVVVVV can make Japanese levels by default, etc) */ + font_idx_level = loc::get_langmeta()->font_idx; + } + else + { + /* If the user has changed the font (wants to make levels + * for a different userbase) then remember that choice. */ + if (!find_main_font_by_name(loc::new_level_font.c_str(), &font_idx_level)) + { + font_idx_level = font_idx_8x8; + } + } + +#ifndef NO_CUSTOM_LEVELS + cl.level_font_name = get_main_font_name(font_idx_level); +#endif +} + static void load_font_filename(bool is_custom, const char* filename) { // Load font.png, and everything that matches *.fontmeta (but not font.fontmeta) @@ -478,6 +520,23 @@ void load_main(void) } FILESYSTEM_freeEnumerate(&handle); font_idx_level = font_idx_8x8; + + // Initialize the font menu options, 8x8 font first + font_idx_options[0] = font_idx_8x8; + font_idx_options_n = 1; + + for (uint8_t i = 0; i < fonts_main.count; i++) + { + if (i == font_idx_8x8) + { + continue; + } + font_idx_options[font_idx_options_n++] = i; + if (font_idx_options_n >= sizeof(font_idx_options)) + { + break; + } + } } void load_custom(const char* name) @@ -884,6 +943,55 @@ const char* get_main_font_name(uint8_t idx) return f->name; } +const char* get_main_font_display_name(uint8_t idx) +{ + Font* f = container_get(&fonts_main, idx); + if (f == NULL) + { + return ""; + } + + if (idx == font_idx_8x8) + { + // Deciding the name for the 8x8 font was harder than I'd like to admit. + if (loc::lang == "en" || loc::get_langmeta()->font_idx != font_idx_8x8) + { + // If you use English, or a CJK language: "english/..." + SDL_strlcpy( + f->display_name, + "english/…", + sizeof(f->display_name) + ); + } + else + { + // If you use another, e.g. German: "english/deutsch/..." + SDL_snprintf( + f->display_name, sizeof(f->display_name), + "english/%s/…", + loc::get_langmeta()->nativename.c_str() + ); + } + } + + return f->display_name; +} + +const char* get_level_font_display_name(void) +{ + if (font_idx_level_is_custom) + { + Font* f = container_get(&fonts_custom, font_idx_level); + if (f == NULL) + { + return ""; + } + return f->display_name; + } + + return get_main_font_display_name(font_idx_level); +} + bool glyph_dimensions(uint32_t flags, uint8_t* glyph_w, uint8_t* glyph_h) { /* Gets the dimensions (glyph_w and glyph_h) of a certain font. diff --git a/desktop_version/src/Font.h b/desktop_version/src/Font.h index 1faa603c..a8d40fce 100644 --- a/desktop_version/src/Font.h +++ b/desktop_version/src/Font.h @@ -59,13 +59,20 @@ namespace font { +// Options in font selection menu +extern uint8_t font_idx_options_n; +extern uint8_t font_idx_options[20]; bool find_main_font_by_name(const char* name, uint8_t* idx); const char* get_main_font_name(uint8_t idx); +const char* get_main_font_display_name(uint8_t idx); +const char* get_level_font_display_name(void); uint8_t get_font_idx_8x8(void); +bool level_font_is_main_idx(uint8_t idx); void set_level_font(const char* name); void set_level_font_interface(void); +void set_level_font_new(void); void load_main(void); void load_custom(const char* name); void unload_custom(void); diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index 506b20db..dda14b3e 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -4560,6 +4560,11 @@ void Game::deserializesettings(tinyxml2::XMLElement* dataNode, struct ScreenSett loc::lang_set = help.Int(pText); } + if (SDL_strcmp(pKey, "new_level_font") == 0) + { + loc::new_level_font = std::string(pText); + } + if (SDL_strcmp(pKey, "roomname_translator") == 0 && loc::show_translator_menu) { roomname_translator::set_enabled(help.Int(pText)); @@ -4837,6 +4842,7 @@ void Game::serializesettings(tinyxml2::XMLElement* dataNode, const struct Screen xml::update_tag(dataNode, "lang", loc::lang.c_str()); xml::update_tag(dataNode, "lang_set", (int) loc::lang_set); + xml::update_tag(dataNode, "new_level_font", loc::new_level_font.c_str()); xml::update_tag(dataNode, "roomname_translator", (int) roomname_translator::enabled); } @@ -6375,6 +6381,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) option(loc::gettext("change author")); option(loc::gettext("change description")); option(loc::gettext("change website")); + option(loc::gettext("change font")); option(loc::gettext("return")); menuyoff = 6; @@ -6394,6 +6401,23 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) menuyoff = 8; maxspacing = 15; break; + case Menu::ed_font: + { + int option_match = -1; + for (uint8_t i = 0; i < font::font_idx_options_n; i++) + { + uint8_t idx = font::font_idx_options[i]; + option(font::get_main_font_display_name(idx), true, PR_FONT_IDX(idx)); + if (font::level_font_is_main_idx(idx)) + { + option_match = i; + } + } + + currentmenuoption = option_match != -1 ? option_match : 0; + maxspacing = 15; + break; + } case Menu::options: option(loc::gettext("gameplay")); option(loc::gettext("graphics")); diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h index 72f2f60c..b15fd298 100644 --- a/desktop_version/src/Game.h +++ b/desktop_version/src/Game.h @@ -53,6 +53,7 @@ namespace Menu ed_desc, ed_music, ed_quit, + ed_font, options, gameplayoptions, speedrunneroptions, diff --git a/desktop_version/src/Localization.cpp b/desktop_version/src/Localization.cpp index 5f7d7acf..d291097f 100644 --- a/desktop_version/src/Localization.cpp +++ b/desktop_version/src/Localization.cpp @@ -15,6 +15,7 @@ namespace loc bool lang_set = false; std::string lang = "en"; std::string lang_custom = ""; +std::string new_level_font = ""; LangMeta langmeta; // language screen list diff --git a/desktop_version/src/Localization.h b/desktop_version/src/Localization.h index fceaa97d..1080c90c 100644 --- a/desktop_version/src/Localization.h +++ b/desktop_version/src/Localization.h @@ -46,6 +46,7 @@ struct TextboxFormat extern bool lang_set; extern std::string lang; extern std::string lang_custom; +extern std::string new_level_font; extern LangMeta langmeta; extern std::vector languagelist; extern int languagelist_curlang; diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index 7142d0b7..171b0c63 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -2592,13 +2592,16 @@ void scriptclass::startgamemode(const enum StartMode mode) game.gamestate = GAMEMODE; } + // Font handling switch (mode) { - case Start_EDITOR: case Start_EDITORPLAYTESTING: case Start_CUSTOM: case Start_CUSTOM_QUICKSAVE: break; + case Start_EDITOR: + font::set_level_font_new(); + break; default: font::set_level_font_interface(); }