VVVVVV/desktop_version/src/Textbox.cpp

413 lines
9.0 KiB
C++
Raw Normal View History

2020-01-01 21:29:24 +01:00
#include "Textbox.h"
#include <SDL.h>
2020-01-01 21:29:24 +01:00
#include "Font.h"
#include "Localization.h"
#include "UTF8.h"
#include "Vlogging.h"
textboxclass::textboxclass(int gap)
2020-01-01 21:29:24 +01:00
{
w = 0;
h = 0;
tl = 0;
prev_tl = 0;
2020-01-01 21:29:24 +01:00
tm = 0;
timer = 0;
xp = 0;
yp = 0;
r = 0;
g = 0;
b = 0;
linegap = gap;
flipme = false;
rand = 0;
large = false;
should_centerx = false;
should_centery = false;
print_flags = PR_FONT_LEVEL;
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
translate = TEXTTRANSLATE_NONE;
function = NULL;
fill_buttons = false;
sprites.clear();
image = TEXTIMAGE_NONE;
crewmate_position = TextboxCrewmatePosition();
original = TextboxOriginalContext();
original.text_case = 1;
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
spacing = TextboxSpacing();
}
void textboxclass::addsprite(int x, int y, int tile, int col)
{
TextboxSprite sprite;
sprite.x = x;
sprite.y = y;
sprite.tile = tile;
sprite.col = col;
sprites.push_back(sprite);
2020-01-01 21:29:24 +01:00
}
void textboxclass::setimage(TextboxImage new_image)
{
image = new_image;
}
void textboxclass::centerx(void)
2020-01-01 21:29:24 +01:00
{
resize();
xp = 160 - (w / 2);
}
void textboxclass::centery(void)
2020-01-01 21:29:24 +01:00
{
resize();
yp = 120 - (h / 2);
}
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
void textboxclass::applyposition(void)
2020-01-01 21:29:24 +01:00
{
resize();
repositionfromcrewmate();
if (should_centerx)
{
centerx();
}
if (should_centery)
{
centery();
}
if (translate == TEXTTRANSLATE_CUTSCENE)
{
adjust();
}
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
}
void textboxclass::adjust(void)
{
resize();
2020-01-01 21:29:24 +01:00
if (xp < 10) xp = 10;
if (yp < 10) yp = 10;
if (xp + w > 310) xp = 310 - w;
if (yp + h > 230) yp = 230 - h;
}
void textboxclass::initcol(int rr, int gg, int bb)
{
r = rr;
g = gg;
b = bb;
tl = 0.5;
2020-01-01 21:29:24 +01:00
}
void textboxclass::update(void)
2020-01-01 21:29:24 +01:00
{
prev_tl = tl;
2020-01-01 21:29:24 +01:00
if (tm == 0)
{
tl += .1f;
if (tl >= 1)
{
tl = 1;
tm = 1;
}
}
else if (tm == 2)
{
tl -= .1f;
if (tl <= 0.5)
{
tl = 0.5;
//this textbox will be removed by updatetextboxes() later
2020-01-01 21:29:24 +01:00
}
}
if (timer > 0)
{
timer--;
if (timer == 0) tm = 2;
}
}
void textboxclass::remove(void)
2020-01-01 21:29:24 +01:00
{
tm = 2;
tl = 1.0f; //Remove mode
}
void textboxclass::removefast(void)
2020-01-01 21:29:24 +01:00
{
tm = 2;
tl = 0.4f; //Remove mode
}
void textboxclass::resize(void)
2020-01-01 21:29:24 +01:00
{
//Set the width and height to the correct sizes
int max = 0;
for (size_t iter = 0; iter < lines.size(); iter++)
2020-01-01 21:29:24 +01:00
{
int len = font::len(print_flags, lines[iter].c_str());
if (len > max) max = len;
2020-01-01 21:29:24 +01:00
}
// 16 for the borders
w = max + 16;
h = lines.size()*(font::height(print_flags) + linegap) + 16 - linegap;
2020-01-01 21:29:24 +01:00
}
void textboxclass::repositionfromcrewmate(void)
{
const int font_height = font::height(print_flags);
// Reposition based off crewmate position, if applicable
if (crewmate_position.override_x)
{
if (crewmate_position.dir == 1) // left
{
xp = crewmate_position.x - w + 16;
}
else if (crewmate_position.dir == 0) // right
{
xp = crewmate_position.x - 16;
}
}
if (crewmate_position.override_y)
{
if (crewmate_position.text_above)
{
if (crewmate_position.dir == 1) // left
{
yp = crewmate_position.y - 16 - (lines.size() * (font_height + linegap) - linegap);
}
else if (crewmate_position.dir == 0) // right
{
yp = crewmate_position.y - 18 - (lines.size() * (font_height + linegap) - linegap);
}
}
else
{
yp = crewmate_position.y + 26;
}
}
}
void textboxclass::addline(const std::string& t)
2020-01-01 21:29:24 +01:00
{
lines.push_back(t);
2020-01-01 21:29:24 +01:00
resize();
if ((int)lines.size() > (large ? 26 : 11))
{
lines.clear();
}
2020-01-01 21:29:24 +01:00
}
void textboxclass::pad(size_t left_pad, size_t right_pad)
{
// Pad the current text with a certain number of spaces on the left and right
if (font::is_rtl(print_flags))
{
// Swap left and right, because left will end up on the right and vice versa...
size_t old_left_pad = left_pad;
left_pad = right_pad;
right_pad = old_left_pad;
}
for (size_t iter = 0; iter < lines.size(); iter++)
{
lines[iter] = std::string(left_pad, ' ') + lines[iter] + std::string(right_pad, ' ');
}
resize();
}
void textboxclass::padtowidth(size_t new_w)
{
/* Pad the current text so that each line is new_w pixels wide.
* Each existing line is centered in that width. */
resize();
uint8_t glyph_w = 8;
font::glyph_dimensions(print_flags, &glyph_w, NULL);
size_t chars_w = SDL_max(w-16, new_w) / glyph_w;
for (size_t iter = 0; iter < lines.size(); iter++)
{
size_t n_glyphs = font::len(print_flags, lines[iter].c_str()) / glyph_w;
signed int padding_needed = chars_w - n_glyphs;
if (padding_needed < 0)
{
continue;
}
size_t left_pad = padding_needed / 2;
size_t right_pad = padding_needed - left_pad;
lines[iter] = std::string(left_pad, ' ') + lines[iter] + std::string(right_pad, ' ');
}
resize();
}
void textboxclass::centertext(void)
{
padtowidth(w-16);
}
int textboxclass::wrap(int pad)
{
/* This function just takes a single-line textbox and wraps it...
* pad = the total number of characters we are going to pad this textbox.
* (or how many characters we should stay clear of 288 pixels width in general)
* Only to be used after a manual graphics.createtextbox[flipme] call,
* or the retranslation of a text box created with said call.
* Returns the new, total height of the textbox. */
if (lines.empty())
{
vlog_error("textboxclass::wrap() has no first line!");
return 16;
}
std::string wrapped = font::string_wordwrap_balanced(
print_flags,
lines[0],
36 * 8 - pad * 8
);
lines.clear();
size_t startline = 0;
size_t newline;
do {
size_t pos_n = wrapped.find('\n', startline);
size_t pos_p = wrapped.find('|', startline);
newline = SDL_min(pos_n, pos_p);
addline(wrapped.substr(startline, newline-startline));
startline = newline + 1;
} while (newline != std::string::npos);
return h;
}
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
void textboxclass::copyoriginaltext(void)
{
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
// Copy the original back, but keep the limit of lines in mind
lines.clear();
for (size_t i = 0; i < original.lines.size(); i++)
{
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
addline(original.lines[i]);
}
}
void textboxclass::applyoriginalspacing(void)
{
if (spacing.centertext)
{
centertext();
}
if (spacing.pad_left > 0 || spacing.pad_right > 0)
{
pad(spacing.pad_left, spacing.pad_right);
}
if (spacing.padtowidth > 0)
{
padtowidth(spacing.padtowidth);
}
}
void textboxclass::updatetext(void)
{
switch (translate)
{
case TEXTTRANSLATE_NONE:
copyoriginaltext();
applyoriginalspacing();
break;
case TEXTTRANSLATE_CUTSCENE:
translatecutscene();
break;
case TEXTTRANSLATE_FUNCTION:
if (function == NULL)
{
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
SDL_assert(0 && "function is NULL!");
break;
}
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
function(this);
}
}
void textboxclass::translatecutscene(void)
{
if (!loc::is_cutscene_translated(original.script_name))
{
copyoriginaltext();
applyoriginalspacing();
return;
}
// English text needs to be un-wordwrapped, translated, and re-wordwrapped
std::string eng;
for (size_t i = 0; i < original.lines.size(); i++)
{
if (i != 0)
{
eng.append("\n");
}
eng.append(original.lines[i]);
}
eng = font::string_unwordwrap(eng);
const loc::TextboxFormat* format = loc::gettext_cutscene(original.script_name, eng, original.text_case);
if (format == NULL || format->text == NULL || format->text[0] == '\0')
{
Save special text box state using functions This adds a way to save the text box state of the crew remaining, ACTION prompt, etc. text boxes by just letting there be a function that is called to retranslate the text box when needed. It also adds a way to ignore translating a text box and to leave it alone, in case there's actually no text in the text box, which is the case with Level Complete and Game Complete. Both ways are now in an enum, TextboxTranslate. The former is TEXTTRANSLATE_FUNCTION and the latter is TEXTTRANSLATE_NONE. The existing way of translating text boxes became TEXTTRANSLATE_CUTSCENE, since it's only used for cutscene scripts. Here's a quick guide to the three ways of creating a text box now. - TEXTTRANSLATE_NONE: You must call graphics.textboxoriginalcontextauto() to save the existing text to the original context of the text box, as that will be copied back to the text box after the text of the text box is updated due to not having a translation. - TEXTTRANSLATE_CUTSCENE: Translates the text from cutscenes.xml, and overrides the spacing (padding and text centering). Shouldn't need to be used outside of scriptclass. - TEXTTRANSLATE_FUNCTION: You must pass in a function that takes in a single parameter, a pointer to the textboxclass object to be modified. General advice when retranslating text is to clear the `lines` vector and then push_back the retranslated text. The function is also solely responsible for spacing. In most cases, you will also need to call graphics.textboxapplyposition() or graphics.textboxadjust() afterwards. (Some text boxes shouldn't use graphics.textboxadjust() as they are within the 10-pixel inner border around the screen that textboxclass::adjust tries to push the text box out of.) This commit doesn't fix every text box just yet, though. But it fixes the Level Complete, Game Complete, crew remaining, and ACTION prompt text boxes, for a start.
2024-01-21 05:27:31 +01:00
copyoriginaltext();
applyoriginalspacing();
return;
}
std::string tra;
if (format->tt)
{
tra = std::string(format->text);
size_t pipe;
while (true)
{
pipe = tra.find('|', 0);
if (pipe == std::string::npos)
{
break;
}
tra.replace(pipe, 1, "\n");
}
}
else
{
tra = font::string_wordwrap_balanced(PR_FONT_LEVEL, format->text, format->wraplimit);
}
lines.clear();
size_t startline = 0;
size_t newline;
do
{
newline = tra.find('\n', startline);
lines.push_back(tra.substr(startline, newline - startline));
startline = newline + 1;
}
while (newline != std::string::npos);
if (format->centertext)
{
centertext();
}
if (format->pad_left > 0 || format->pad_right > 0)
{
pad(format->pad_left, format->pad_right);
}
if (format->padtowidth > 0)
{
padtowidth(format->padtowidth);
}
}