#include "RoomnameTranslator.h" #include "Constants.h" #include "Font.h" #include "Game.h" #include "Graphics.h" #include "GraphicsUtil.h" #include "KeyPoll.h" #include "LevelDebugger.h" #include "Localization.h" #include "LocalizationMaint.h" #include "Map.h" #include "Script.h" #include "UtilityClass.h" #include "VFormat.h" namespace roomname_translator { bool enabled = false; bool edit_mode = false; bool expl_mode = false; bool help_screen = false; SDL_Surface* dimbuffer; SDL_Rect fullscreen_rect; void set_enabled(bool value) { enabled = value; edit_mode = false; } bool is_pausing(void) { return enabled && edit_mode; } static void print_explanation(const char* explanation) { const char* use_explanation = explanation; if (explanation == NULL || explanation[0] == '\0') { use_explanation = "[explanation not yet set]"; } else if (SDL_strcmp(explanation, ".") == 0) { use_explanation = "[no explanation]"; } font::print_wrap(PR_BOR | PR_FONT_8X8, 0, 10, use_explanation, 0,192,255, 8, 320); } void overlay_render(bool* force_roomname_hidden, bool* roomname_untranslated, int* roomname_r, int* roomname_g, int* roomname_b) { if (level_debugger::is_active()) { return; } if (edit_mode || help_screen) { fullscreen_rect.x = 0; fullscreen_rect.y = 0; fullscreen_rect.w = 320; fullscreen_rect.h = 240; graphics.set_blendmode(SDL_BLENDMODE_BLEND); graphics.fill_rect(graphics.getRGBA(0, 0, 0, 96)); graphics.set_blendmode(SDL_BLENDMODE_NONE); if (help_screen) { font::print(PR_BOR | PR_FONT_8X8, 0, 0, "=== Room name translation mode help ===", 255,255,255); if (expl_mode) { font::print_wrap( PR_BOR | PR_FONT_8X8, 0, 20, "You can currently access EXPL mode to\n" "set explanations for room names.\n" "(Use Ctrl+E to switch to NAME mode.)", 255,255,255 ); const char* first_part = "Unexplained room names are "; font::print(PR_BOR | PR_FONT_8X8, 0, 60, first_part, 255,255,255); font::print(PR_BOR | PR_FONT_8X8, font::len(PR_FONT_8X8, first_part), 60, "cyan.", 64, 255, 255-help.glow); } else { font::print_wrap( PR_BOR | PR_FONT_8X8, 0, 20, "You can currently access NAME mode to\n" "translate room names.\n" "(Use Ctrl+E to switch to EXPL mode.)", 255,255,255 ); const char* first_part = "English room names are "; font::print(PR_BOR | PR_FONT_8X8, 0, 60, first_part, 255,255,255); font::print(PR_BOR | PR_FONT_8X8, font::len(PR_FONT_8X8, first_part), 60, "cyan.", 0, 192, 255-help.glow); } font::print(PR_BOR | PR_FONT_8X8, 0, 80, "KEYS:", 255,255,255); if (expl_mode) { font::print(PR_BOR | PR_FONT_8X8, 0, 90, "Tab - switch between play/expl modes", 255,255,255); font::print(PR_BOR | PR_FONT_8X8, 0, 100, "E/Enter - set room name explanation", 255,255,255); } else { font::print(PR_BOR | PR_FONT_8X8, 0, 90, "Tab - switch between play/name modes", 255,255,255); font::print(PR_BOR | PR_FONT_8X8, 0, 100, "E/Enter - set room name translation", 255,255,255); } font::print(PR_BOR | PR_FONT_8X8, 0, 110, "I - toggle invincibility", 255,255,255); if (expl_mode) { font::print(PR_BOR | PR_FONT_8X8, 0, 120, ". - set blank explanation", 255,255,255); } *force_roomname_hidden = true; return; } else if (expl_mode) { font::print(PR_BOR | PR_FONT_8X8, 0, 0, "Expl mode [TAB]", 255,255,255); } else { font::print(PR_BOR | PR_FONT_8X8, 0, 0, "Name mode [TAB]", 255,255,255); } } else { font::print(PR_BOR | PR_FONT_8X8, 0, 0, "Play mode [TAB]", 255,255,255); font::print(PR_BOR | PR_FONT_8X8, 320-64, 10, "F1: Help", 192,192,192); } char buffer[SCREEN_WIDTH_CHARS + 1]; int n_left; if (expl_mode) { n_left = map.custommode ? loc::n_unexplained_roomnames_custom : loc::n_unexplained_roomnames; } else { n_left = map.custommode ? loc::n_untranslated_roomnames_custom : loc::n_untranslated_roomnames; } vformat_buf(buffer, sizeof(buffer), "{n|digits=3|spaces} left", "n:int", n_left); font::print(PR_BOR | PR_FONT_8X8, 144, 0, buffer, 255,255,255); if (map.invincibility) { font::print(PR_BOR | PR_FONT_8X8, 224, 0, "INV", 255,255,128); } vformat_buf(buffer, sizeof(buffer), "({x|digits=2|spaces},{y|digits=2|spaces})", "x:int, y:int", game.roomx % 100, game.roomy % 100 ); font::print(PR_BOR | PR_FONT_8X8, 320-56, 0, buffer, 255,255,255); if (map.roomname_special) { if (edit_mode) { print_explanation("This is a special room name, which cannot be translated in-game. Please see roomnames_special"); } } else if (map.roomname[0] == '\0') { // No room name at all, so no translation/explanation interface if (edit_mode) { font::print(PR_CEN | PR_BOR | PR_FONT_8X8, -1, 229-font::height(PR_FONT_LEVEL), "[no roomname]", 0,192,255); } } else if (!expl_mode) { // Name mode affects play mode a bit as well... bool roomname_is_translated = loc::get_roomname_translation(map.custommode, game.roomx, game.roomy)[0] != '\0'; *roomname_untranslated = !roomname_is_translated; if (edit_mode) { const char* english_roomname = map.roomname; font::print(PR_CEN | PR_BOR | PR_FONT_8X8, -1, 229-font::height(PR_FONT_LEVEL), english_roomname, 0,192,255); print_explanation(loc::get_roomname_explanation(map.custommode, game.roomx, game.roomy)); if (key.textentry()) { *force_roomname_hidden = true; graphics.render_roomname(PR_FONT_LEVEL, key.keybuffer.c_str(), 255,255,255); int name_w = font::len(PR_FONT_LEVEL, key.keybuffer.c_str()); font::print(PR_BOR | PR_FONT_LEVEL | PR_RTL_XFLIP, (320-name_w)/2+name_w, 231, "_", 255,255,255); } else if (!roomname_is_translated) { *force_roomname_hidden = true; graphics.render_roomname(PR_FONT_8X8, "[no translation]", 255,255,128); } } else if (!roomname_is_translated) { *roomname_r = 0; *roomname_g = 192; *roomname_b = 255 - help.glow; } } else { // Explanation mode! const char* explanation = loc::get_roomname_explanation(map.custommode, game.roomx, game.roomy); if (explanation[0] == '\0') { *roomname_r = 64; *roomname_g = 255; *roomname_b = 255 - help.glow; } if (edit_mode) { if (key.textentry()) { print_explanation((key.keybuffer + "_").c_str()); font::print_wrap(PR_BOR | PR_FONT_8X8, 0, 90, "Use \".\" to set no explanation", 255,255,255, 8, 320); } else { print_explanation(explanation); } } } } static bool key_pressed_once(SDL_Keycode keyc, bool* held) { if (key.isDown(keyc)) { if (!*held) { *held = true; return true; } } else { *held = false; } return false; } static void save_explanation(const char* explanation, const char* success_message) { if (loc::save_roomname_explanation_to_files(map.custommode, game.roomx, game.roomy, explanation)) { graphics.createtextboxflipme(success_message, -1, 176, TEXT_COLOUR("gray")); graphics.textboxprintflags(PR_FONT_8X8); graphics.textboxcenterx(); graphics.textboxtimer(25); } else { graphics.createtextboxflipme("ERROR: Could not save to all langs!", -1, 176, TEXT_COLOUR("red")); graphics.textboxprintflags(PR_FONT_8X8); graphics.textboxcenterx(); graphics.textboxtimer(50); } graphics.textboxoriginalcontextauto(); graphics.textboxapplyposition(); } static void save_translation(const char* translation) { if (loc::save_roomname_to_file(loc::lang, map.custommode, game.roomx, game.roomy, translation, NULL)) { graphics.createtextboxflipme("Translation saved!", -1, 176, TEXT_COLOUR("gray")); graphics.textboxprintflags(PR_FONT_8X8); graphics.textboxcenterx(); graphics.textboxtimer(25); } else { graphics.createtextboxflipme("ERROR: Could not save!", -1, 144, TEXT_COLOUR("red")); graphics.addline(""); graphics.addline("1) Do the language files exist?"); graphics.addline("2) Make sure there is no \"lang\""); graphics.addline(" folder next to the regular saves."); graphics.textboxprintflags(PR_FONT_8X8); graphics.textboxcenterx(); graphics.textboxtimer(180); } graphics.textboxoriginalcontextauto(); graphics.textboxapplyposition(); } bool held_tab = false; bool held_i = false; bool held_escape = false; bool held_return = false; bool held_e = false; bool held_period = false; bool held_f1 = false; bool overlay_input(void) { // Returns true if input "caught" and should not go to gameinput if (key.isDown(SDLK_ESCAPE) && held_escape) { // Avoid opening the pause menu return true; } else { held_escape = false; } if (help_screen) { if ((key.isDown(SDLK_LCTRL) || key.isDown(SDLK_RCTRL)) && key_pressed_once(SDLK_e, &held_e)) { expl_mode = !expl_mode; } if (key_pressed_once(SDLK_ESCAPE, &held_escape) || key_pressed_once(SDLK_F1, &held_f1)) { help_screen = false; } return true; } if (key.textentry()) { if (key_pressed_once(SDLK_ESCAPE, &held_escape)) { // Without saving key.disabletextentry(); } if (key_pressed_once(SDLK_RETURN, &held_return)) { key.disabletextentry(); if (!expl_mode) { if (loc::lang == "en") { graphics.createtextboxflipme("ERROR: Can't add EN-EN translation", -1, 176, TEXT_COLOUR("red")); graphics.textboxoriginalcontextauto(); graphics.textboxprintflags(PR_FONT_8X8); graphics.textboxcenterx(); graphics.textboxtimer(50); graphics.textboxapplyposition(); } else { save_translation(key.keybuffer.c_str()); } } else { save_explanation(key.keybuffer.c_str(), "Explanation saved!"); } edit_mode = false; game.mapheld = true; } return true; } if (key_pressed_once(SDLK_F1, &held_f1)) { help_screen = true; } if (key_pressed_once(SDLK_TAB, &held_tab) && !level_debugger::is_active()) { edit_mode = !edit_mode; } if (key_pressed_once(SDLK_i, &held_i)) { if (game.intimetrial) { // We'll let you enable it in a time trial, but with a twist. if (!game.timetrialcheater) { game.sabotage_time_trial(); } } else if (game.incompetitive()) { return edit_mode; } map.invincibility = !map.invincibility; } if (edit_mode) { if (key_pressed_once(SDLK_ESCAPE, &held_escape)) { edit_mode = false; return true; } if ((key.isDown(SDLK_LCTRL) || key.isDown(SDLK_RCTRL)) && key_pressed_once(SDLK_e, &held_e)) { expl_mode = !expl_mode; return true; } if (key_pressed_once(SDLK_RETURN, &held_return) || key_pressed_once(SDLK_e, &held_e)) { if (map.roomname_special || map.roomname[0] == '\0') { return true; } key.enabletextentry(); if (!expl_mode) { key.keybuffer = loc::get_roomname_translation(map.custommode, game.roomx, game.roomy); } else { key.keybuffer = loc::get_roomname_explanation(map.custommode, game.roomx, game.roomy); } } if (expl_mode && key_pressed_once(SDLK_PERIOD, &held_period)) { const char* old_explanation = loc::get_roomname_explanation(map.custommode, game.roomx, game.roomy); const char* new_explanation = NULL; const char* success_message; if (old_explanation[0] == '\0') { new_explanation = "."; success_message = "Blank explanation set!"; } else if (SDL_strcmp(old_explanation, ".") == 0) { new_explanation = ""; success_message = "Blank explanation deleted!"; } if (new_explanation != NULL) { save_explanation(new_explanation, success_message); } } } return edit_mode; } }