2020-01-01 21:29:24 +01:00
|
|
|
#include "Textbox.h"
|
2020-07-19 21:43:29 +02:00
|
|
|
|
2022-12-30 22:57:24 +01:00
|
|
|
#include <SDL.h>
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2023-01-12 05:27:52 +01:00
|
|
|
#include "Font.h"
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
#include "Localization.h"
|
2023-02-23 04:14:59 +01:00
|
|
|
#include "UTF8.h"
|
2024-01-21 06:33:57 +01:00
|
|
|
#include "Vlogging.h"
|
2023-01-12 05:27:52 +01:00
|
|
|
|
2024-01-17 20:26:52 +01:00
|
|
|
textboxclass::textboxclass(int gap)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
w = 0;
|
|
|
|
h = 0;
|
|
|
|
tl = 0;
|
2020-04-29 06:49:15 +02:00
|
|
|
prev_tl = 0;
|
2020-01-01 21:29:24 +01:00
|
|
|
tm = 0;
|
|
|
|
timer = 0;
|
2020-07-06 22:04:34 +02:00
|
|
|
|
|
|
|
xp = 0;
|
|
|
|
yp = 0;
|
|
|
|
r = 0;
|
|
|
|
g = 0;
|
|
|
|
b = 0;
|
2024-01-17 20:26:52 +01:00
|
|
|
linegap = gap;
|
2021-03-20 03:51:36 +01:00
|
|
|
|
|
|
|
flipme = false;
|
2021-03-23 22:29:32 +01:00
|
|
|
|
|
|
|
rand = 0;
|
2023-01-13 05:11:39 +01:00
|
|
|
|
2022-11-30 18:56:44 +01:00
|
|
|
large = false;
|
|
|
|
|
2024-01-21 02:02:35 +01:00
|
|
|
should_centerx = false;
|
|
|
|
should_centery = false;
|
|
|
|
|
2023-01-13 05:11:39 +01:00
|
|
|
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;
|
2023-03-18 22:31:13 +01:00
|
|
|
fill_buttons = false;
|
2023-08-06 00:34:15 +02:00
|
|
|
|
|
|
|
sprites.clear();
|
2023-08-20 19:11:44 +02:00
|
|
|
|
|
|
|
image = TEXTIMAGE_NONE;
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
|
|
|
|
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();
|
2024-01-21 21:39:15 +01:00
|
|
|
|
|
|
|
other_textbox_index = -1;
|
2023-08-06 00:34:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2023-08-20 19:11:44 +02:00
|
|
|
void textboxclass::setimage(TextboxImage new_image)
|
|
|
|
{
|
|
|
|
image = new_image;
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void textboxclass::centerx(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
resize();
|
|
|
|
xp = 160 - (w / 2);
|
|
|
|
}
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
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();
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
repositionfromcrewmate();
|
2024-01-21 02:02:35 +01:00
|
|
|
if (should_centerx)
|
|
|
|
{
|
|
|
|
centerx();
|
|
|
|
}
|
|
|
|
if (should_centery)
|
|
|
|
{
|
|
|
|
centery();
|
|
|
|
}
|
2024-01-21 19:48:39 +01:00
|
|
|
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;
|
Textboxes: Don't use separate RGB variables
Text boxes have `r`, `g`, and `b`, and `tr`, `tg`, and `tb`. `tr`, `tg`,
and `tb` are the real colors of the text box, and `r`, `g`, and `b` are
merely the colors of the text box as the text box's alpha value is
applied to them.
Compare this with, say, activity zones (which are drawn like text boxes
but aren't text boxes): There is `activity_r`, `activity_g`, and
`activity_b`, and when they're drawn they're all multiplied by
`act_alpha`.
So just do the same thing here. Ditch the `tr`, `tg`, and `tb`
variables, and make `r`, `g`, and `b` the new `tr`, `tg`, and `tb`
variables. That way, there's simply less state to have to update
separately. So we can get rid of `textboxclass::setcol()` as well.
2021-09-06 09:48:42 +02:00
|
|
|
tl = 0.5;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void textboxclass::update(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-29 06:49:15 +02: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;
|
2020-04-29 03:38:43 +02:00
|
|
|
//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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void textboxclass::remove(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
tm = 2;
|
|
|
|
tl = 1.0f; //Remove mode
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void textboxclass::removefast(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
tm = 2;
|
|
|
|
tl = 0.4f; //Remove mode
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void textboxclass::resize(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
//Set the width and height to the correct sizes
|
2021-09-06 05:46:46 +02:00
|
|
|
int max = 0;
|
2021-09-13 06:02:15 +02:00
|
|
|
for (size_t iter = 0; iter < lines.size(); iter++)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2023-03-05 00:32:58 +01:00
|
|
|
int len = font::len(print_flags, lines[iter].c_str());
|
2023-01-15 01:31:02 +01:00
|
|
|
if (len > max) max = len;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
2022-12-30 22:57:24 +01:00
|
|
|
// 16 for the borders
|
2023-01-12 05:27:52 +01:00
|
|
|
w = max + 16;
|
2024-01-17 20:26:52 +01:00
|
|
|
h = lines.size()*(font::height(print_flags) + linegap) + 16 - linegap;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-07 00:41:49 +02:00
|
|
|
void textboxclass::addline(const std::string& t)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2021-09-13 06:02:15 +02:00
|
|
|
lines.push_back(t);
|
2020-01-01 21:29:24 +01:00
|
|
|
resize();
|
2022-11-30 18:56:44 +01:00
|
|
|
if ((int)lines.size() > (large ? 26 : 11))
|
|
|
|
{
|
|
|
|
lines.clear();
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
2022-12-30 22:57: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
|
2024-01-07 04:42:53 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-12-30 22:57:24 +01:00
|
|
|
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();
|
2023-01-17 22:18:39 +01:00
|
|
|
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;
|
2022-12-30 22:57:24 +01:00
|
|
|
for (size_t iter = 0; iter < lines.size(); iter++)
|
|
|
|
{
|
Base text box padding/centering on font width instead of codepoints
Stuff like centertext="1" and padtowidth="264" in cutscene translations
looked wrong in RTL mode, both with Arabic and English text. For Arabic
text, I could easily fix the problem by not counting the number of
codepoints (and assuming they all have the same glyph width), but by
instead taking the width of the string as reported for the font, and
dividing it by the glyph width. This leaves English text still looking
weird in RTL mode. But this shouldn't be a problem either: the Arabic
translations will probably be in Arabic (where the problem doesn't
happen), and I can get English text to show up fine by wrapping it in
U+2066 LEFT-TO-RIGHT ISOLATE and U+2069 POP DIRECTIONAL ISOLATE. So it
looks like an inherent quirk of bidi, that translators familiar with
bidi can easily grasp and fix.
This is main-game only functionality, so it shouldn't break existing
custom levels. We should just make sure textboxes in other languages
aren't broken, but from my testing, it's completely fine - in fact, it
should've improved if it was broken.
2024-01-04 22:19:50 +01:00
|
|
|
size_t n_glyphs = font::len(print_flags, lines[iter].c_str()) / glyph_w;
|
2022-12-30 22:57:24 +01:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-03-18 23:24:14 +01:00
|
|
|
void textboxclass::centertext(void)
|
2022-12-30 22:57:24 +01:00
|
|
|
{
|
|
|
|
padtowidth(w-16);
|
|
|
|
}
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
|
2024-01-21 06:33:57 +01:00
|
|
|
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 textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
{
|
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 textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
{
|
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)
|
2024-01-21 00:26:36 +01:00
|
|
|
{
|
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;
|
2024-01-21 00:26:36 +01:00
|
|
|
}
|
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();
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
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();
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
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);
|
|
|
|
|
2024-01-21 23:10:43 +01:00
|
|
|
resize();
|
|
|
|
|
Save textbox state, allow lang switches w/ textbox
This allows switching languages while a text box is on screen by saving
the necessary state for a text box to be retranslated when the language
is switched.
This saves the state of the position and direction of the crewmate that
the text box position is based off of (if applicable), and the text
case of the text box, the script name of the script, and the original
(English) lines of the text box. I did not explicitly label the original
lines as English lines except in a main game context, because
technically, custom levels could have original lines in a different
language.
Unfortunately, this doesn't work for every text box in the game.
Notably, the Level Complete, Game Complete, number of crewmates
remaining, trinket collection, Intermission 1 guides, etc. text boxes
are special and require further fixes, but that will be coming in later
commits.
2024-01-19 05:21:02 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|