VVVVVV/desktop_version/src/RoomnameTranslator.cpp

465 lines
15 KiB
C++

#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;
}
}