re3/src/render/Font.cpp

1938 lines
50 KiB
C++
Raw Normal View History

2020-04-26 20:49:24 +00:00
#include "common.h"
#include "Sprite2d.h"
#include "TxdStore.h"
#include "Font.h"
2020-11-07 18:54:38 +00:00
#ifdef BUTTON_ICONS
#include "FileMgr.h"
#endif
2020-06-07 01:11:10 +00:00
#include "Timer.h"
2020-04-26 20:49:24 +00:00
void
AsciiToUnicode(const char *src, wchar *dst)
{
while((*dst++ = (unsigned char)*src++) != '\0');
}
void
UnicodeStrcat(wchar *dst, wchar *append)
{
UnicodeStrcpy(&dst[UnicodeStrlen(dst)], append);
}
void
UnicodeStrcpy(wchar *dst, const wchar *src)
{
while((*dst++ = *src++) != '\0');
}
int
UnicodeStrlen(const wchar *str)
{
int len;
for(len = 0; *str != '\0'; len++, str++);
return len;
}
2020-10-11 07:39:04 +00:00
void
UnicodeMakeUpperCase(wchar *dst, const wchar *src) //idk what to do with it, seems to be incorrect implementation by R*
{
while (*src != '\0') {
if (*src < 'a' || *src > 'z')
*dst = *src;
else
*dst = *src - 32;
dst++;
src++;
}
*dst = '\0';
}
2020-04-26 20:49:24 +00:00
CFontDetails CFont::Details;
int16 CFont::NewLine;
CSprite2d CFont::Sprite[MAX_FONTS];
2020-06-07 01:11:10 +00:00
CFontRenderState CFont::RenderState;
2020-04-26 20:49:24 +00:00
#ifdef MORE_LANGUAGES
uint8 CFont::LanguageSet = FONT_LANGSET_EFIGS;
int32 CFont::Slot = -1;
#define JAP_TERMINATION (0x8000 | '~')
2020-06-07 07:36:37 +00:00
int16 CFont::Size[LANGSET_MAX][MAX_FONTS][210] = {
2020-04-26 20:49:24 +00:00
{
#else
2020-06-07 01:11:10 +00:00
int16 CFont::Size[MAX_FONTS][210] = {
2020-04-26 20:49:24 +00:00
#endif
2020-06-07 01:11:10 +00:00
{
//FONT2 EFIGS
//SPC,!, $, %, &, ', [, ], +, , -, .,
12, 9, 22, 17, 19, 19, 25, 4, 33, 33, 25, 35, 11, 10, 6, 33,
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ??,
18, 10, 17, 17, 17, 17, 17, 15, 12, 16, 5, 30, 30, 30, 30, 30,
// A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
12, 16, 19, 16, 19, 18, 18, 17, 22, 11, 17, 18, 18, 30, 22, 19,
//P, Q, R, S, T, U, V, W, X, Y, Z, ??, ??, ??, <20>, \,
2021-02-18 09:34:23 +00:00
#ifdef FIX_BUGS
22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 10, 19,
#else
22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 19, 19,
#endif
//??,a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
12, 14, 11, 11, 16, 11, 12, 14, 14, 10, 13, 12, 10, 19, 18, 12,
//p, q, r, s, t, u, v, w, x, y, z, ??, ??, ??, ??, ??,
16, 13, 13, 11, 12, 15, 12, 15, 13, 12, 12, 37, 33, 37, 35, 37,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
16, 16, 16, 16, 33, 17, 18, 18, 18, 18, 11, 11, 11, 11, 19, 19,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
19, 19, 19, 19, 19, 19, 15, 14, 14, 14, 14, 20, 14, 11, 11, 11,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
2021-02-18 09:34:23 +00:00
#ifdef FIX_BUGS
11, 10, 10, 10, 10, 12, 12, 12, 12, 15, 15, 15, 15, 22, 18, 21,
#else
11, 10, 10, 10, 10, 12, 12, 12, 12, 15, 15, 15, 15, 24, 18, 21,
#endif
//i,BLANKS
10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
2021-02-18 09:34:23 +00:00
//space, unprop
19, 16
2020-06-07 01:11:10 +00:00
},
{
//FONT1 EFIGS
//Characters with a '2' refer to the Pricedown font.
//Characters that are referred as '*I' are characters that contain icons for PS2/XBOX, but contain regular characters on PC
//in order to display them properly in the Keyboard controls menu.
//!2,!, *I,(R), $, %, &, ', [, ], *I, +, , -, ., *I,
15, 7, 31, 25, 20, 23, 21, 7, 11, 10, 26, 14, 6, 12, 6, 26,
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, *I, *I, *I, *I, ?,
20, 7, 20, 20, 21, 20, 20, 19, 21, 20, 8, 30, 24, 30, 24, 19,
//TM,A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
20, 22, 22, 21, 22, 18, 18, 22, 22, 9, 14, 21, 18, 27, 21, 24,
//P, Q, R, S, T, U, V, W, X, Y, Z, *I, \, *I, <20>, <20>,
2021-02-18 09:34:23 +00:00
#ifdef FIX_BUGS
22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 7, 19,
#else
22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 10, 19,
#endif
//(C),a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
10, 17, 17, 16, 17, 17, 11, 17, 17, 7, 7, 18, 7, 25, 17, 17,
//p, q, r, s, t, u, v, w, x, y, z, *I, *I, $2, (2, )2,
17, 17, 11, 17, 11, 17, 18, 25, 19, 18, 17, 28, 26, 20, 15, 15,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
20, 20, 20, 20, 29, 22, 19, 19, 19, 19, 9, 9, 9, 9, 23, 23,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
23, 23, 24, 24, 24, 24, 20, 19, 17, 17, 17, 30, 16, 17, 17, 17,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
2021-02-18 09:34:23 +00:00
#ifdef FIX_BUGS
17, 11, 11, 15, 12, 17, 17, 17, 17, 17, 17, 17, 17, 21, 17, 19,
#else
17, 11, 11, 15, 12, 17, 17, 17, 17, 17, 17, 17, 17, 19, 20, 20,
#endif
//02,12,22, 32, 42, 52, 62, 72, 82, 92, :2, A2, B2, C2, D2, E2,
20, 18, 19, 19, 21, 19, 19, 19, 19, 19, 16, 19, 19, 19, 20, 19,
//F2,G2,H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2,
16, 19, 19, 9, 19, 20, 14, 29, 19, 19, 19, 19, 19, 19, 21, 19,
//V2,W2,X2, Y2, Z2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2,
20, 32, 20, 19, 19, 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9,
//<2F>2,<2C>2,<2C>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, '2, .2,
2021-02-18 09:34:23 +00:00
#ifdef FIX_BUGS
9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 10, 9,
#else
9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 21, 21, 10, 9,
#endif
2021-02-18 09:34:23 +00:00
//space, unprop
10, 20
2020-06-07 01:11:10 +00:00
}
2021-02-05 12:53:24 +00:00
2020-04-26 20:49:24 +00:00
#ifdef MORE_LANGUAGES
},
{
2021-02-18 09:34:23 +00:00
{
5, 9, 9, 0, 17, 17, 23, 3, 21, 18, 0, 8, 3, 8, 3, 0,
16, 9, 16, 16, 15, 19, 15, 14, 17, 17, 4, 4, 0, 0, 0, 17,
19, 17, 19, 15, 21, 18, 19, 16, 21, 13, 15, 21, 20, 28, 21, 18,
22, 17, 21, 20, 18, 18, 20, 26, 22, 18, 18, 0, 8, 0, 9, 8,
0, 14, 11, 12, 16, 11, 13, 13, 15, 10, 14, 15, 11, 21, 17, 10,
20, 15, 12, 12, 16, 17, 13, 16, 13, 21, 11, 0, 0, 0, 0, 0,
20, 19, 19, 22, 27, 15, 18, 18, 20, 26, 21, 23, 17, 22, 21, 17,
26, 25, 26, 17, 20, 26, 17, 16, 11, 12, 13, 21, 11, 17, 17, 12,
21, 17, 17, 15, 24, 16, 10, 20, 23, 16, 7, 9, 16, 23, 12, 11,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19,
19, 16
2020-04-26 20:49:24 +00:00
},
2021-02-18 09:34:23 +00:00
{
11, 5, 10, 15, 19, 22, 20, 5, 9, 8, 11, 12, 5, 12, 6, 12,
19, 5, 18, 19, 20, 18, 19, 18, 20, 19, 5, 6, 26, 12, 30, 19,
23, 21, 20, 20, 20, 16, 16, 21, 19, 5, 13, 19, 16, 24, 20, 21,
20, 21, 20, 19, 17, 20, 21, 30, 22, 21, 20, 25, 13, 30, 5, 9,
10, 15, 15, 14, 15, 16, 10, 15, 15, 5, 5, 15, 5, 23, 15, 16,
15, 15, 9, 16, 10, 15, 17, 24, 18, 15, 15, 27, 5, 19, 2, 2,
20, 20, 16, 23, 30, 19, 20, 20, 21, 24, 19, 19, 20, 23, 22, 19,
27, 29, 25, 20, 20, 28, 24, 16, 16, 14, 19, 25, 16, 16, 16, 17,
19, 16, 16, 17, 25, 19, 15, 23, 26, 21, 16, 14, 22, 20, 16, 19,
15, 14, 15, 16, 17, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15,
13, 15, 15, 7, 15, 16, 13, 23, 15, 15, 15, 15, 15, 15, 17, 15,
16, 24, 17, 17, 17, 15, 15, 13, 20, 23, 15, 17, 17, 16, 24, 15,
15, 15, 23, 18, 15, 23, 26, 23, 16, 15, 23, 15, 15, 19, 2, 2,
10, 20
},
},
{
2020-04-26 20:49:24 +00:00
{
2021-02-18 09:34:23 +00:00
//FONT2 EFIGS
//SPC,!, $, %, &, ', [, ], +, , -, .,
12, 9, 22, 17, 19, 19, 25, 4, 33, 33, 25, 35, 11, 10, 6, 33,
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ??,
18, 10, 17, 17, 17, 17, 17, 15, 12, 16, 5, 30, 30, 30, 30, 30,
// A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
12, 16, 19, 16, 19, 18, 18, 17, 22, 11, 17, 18, 18, 30, 22, 19,
//P, Q, R, S, T, U, V, W, X, Y, Z, ??, ??, ??, <20>, \,
22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 10, 19,
//??,a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
12, 14, 11, 11, 16, 11, 12, 14, 14, 10, 13, 12, 10, 19, 18, 12,
//p, q, r, s, t, u, v, w, x, y, z, ??, ??, ??, ??, ??,
16, 13, 13, 11, 12, 15, 12, 15, 13, 12, 12, 37, 33, 37, 35, 37,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
16, 16, 16, 16, 33, 17, 18, 18, 18, 18, 11, 11, 11, 11, 19, 19,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
19, 19, 19, 19, 19, 19, 15, 14, 14, 14, 14, 20, 14, 11, 11, 11,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
11, 10, 10, 10, 10, 12, 12, 12, 12, 15, 15, 15, 15, 22, 18, 21,
//i,BLANKS
10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
2020-04-26 20:49:24 +00:00
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
2021-02-18 09:34:23 +00:00
//space, unprop
19, 16
2020-04-26 20:49:24 +00:00
},
{
2021-02-18 09:34:23 +00:00
//FONT1 EFIGS
//Characters with a '2' refer to the Pricedown font.
//Characters that are referred as '*I' are characters that contain icons for PS2/XBOX, but contain regular characters on PC
//in order to display them properly in the Keyboard controls menu.
//!2,!, *I,(R), $, %, &, ', [, ], *I, +, , -, ., *I,
15, 7, 31, 25, 20, 23, 21, 7, 11, 10, 26, 14, 6, 12, 6, 26,
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, *I, *I, *I, *I, ?,
20, 7, 20, 20, 21, 20, 20, 19, 21, 20, 8, 30, 24, 30, 24, 19,
//TM,A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
20, 22, 22, 21, 22, 18, 18, 22, 22, 9, 14, 21, 18, 27, 21, 24,
//P, Q, R, S, T, U, V, W, X, Y, Z, *I, \, *I, <20>, <20>,
22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 7, 19,
//(C),a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
10, 17, 17, 16, 17, 17, 11, 17, 17, 7, 7, 18, 7, 25, 17, 17,
//p, q, r, s, t, u, v, w, x, y, z, *I, *I, $2, (2, )2,
17, 17, 11, 17, 11, 17, 18, 25, 19, 18, 17, 28, 26, 20, 15, 15,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
20, 20, 20, 20, 29, 22, 19, 19, 19, 19, 9, 9, 9, 9, 23, 23,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
23, 23, 24, 24, 24, 24, 20, 19, 17, 17, 17, 30, 16, 17, 17, 17,
//<2F>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>, <20>,
17, 11, 11, 15, 12, 17, 17, 17, 17, 17, 17, 17, 17, 21, 17, 19,
//02,12,22, 32, 42, 52, 62, 72, 82, 92, :2, A2, B2, C2, D2, E2,
20, 18, 19, 19, 21, 19, 19, 19, 19, 19, 16, 19, 19, 19, 20, 19,
//F2,G2,H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2,
16, 19, 19, 9, 19, 20, 14, 29, 19, 19, 19, 19, 19, 19, 21, 19,
//V2,W2,X2, Y2, Z2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2,
20, 32, 20, 19, 19, 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9,
//<2F>2,<2C>2,<2C>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, <20>2, '2, .2,
9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 10, 9,
//space, unprop
10, 20
2020-04-26 20:49:24 +00:00
}
}
#endif
};
#ifdef MORE_LANGUAGES
int16 Size_jp[] = {
15, 14, 16, 20, 19, 26, 22, 11, 18, 18, 27, 26, 13, //; 0
19, 20, 27, 19, 15, 19, 19, 21, 19, 20, 18, 19, 15, //; 13
13, 28, 15, 32, 15, 35, 15, 19, 19, 19, 19, 17, 16, //; 26
19, 20, 15, 19, 20, 14, 17, 19, 19, 19, 19, 19, 19, //; 39
19, 19, 20, 25, 20, 19, 19, 33, 31, 39, 37, 39, 37, //; 52
21, 21, 21, 19, 17, 15, 23, 21, 15, 19, 20, 16, 19, //; 65
19, 19, 20, 20, 17, 22, 19, 22, 22, 19, 22, 22, 23, //; 78
35, 35, 35, 35, 37, 19, 19, 19, 19, 29, 19, 19, 19, //; 91
19, 19, 9, 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, //; 104
19, 19, 19, 19, 19, 30, 19, 19, 19, 19, 19, 10, 10, //; 118
10, 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 23, 35, //; 131
12, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, //; 144
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, //; 157
19, 19, 19, 11, 19, 19, 19, 19, 19, 19, 19, 19, 19, //; 170
19, 19, 19, 19, 19, 19, 19, 19, 19, 21
};
#endif
wchar foreign_table[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 177, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 175,
128, 129, 130, 0, 131, 0, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
0, 173, 142, 143, 144, 0, 145, 0, 0, 146, 147, 148, 149, 0, 0, 150,
151, 152, 153, 0, 154, 0, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
0, 174, 165, 166, 167, 0, 168, 0, 0, 169, 170, 171, 172, 0, 0, 0,
};
2020-06-07 07:36:37 +00:00
union tFontRenderStatePointer
{
CFontRenderState *pRenderState;
wchar *pStr;
2020-06-07 01:11:10 +00:00
2020-06-07 07:36:37 +00:00
void Align()
{
if ((uintptr)pStr % 4)
pStr++;
}
};
tFontRenderStatePointer FontRenderStatePointer;
2020-06-07 01:11:10 +00:00
uint8 FontRenderStateBuf[1024];
2020-11-05 15:05:16 +00:00
#ifdef BUTTON_ICONS
CSprite2d CFont::ButtonSprite[MAX_BUTTON_ICONS];
int CFont::PS2Symbol = BUTTON_NONE;
2020-11-07 18:54:38 +00:00
int CFont::ButtonsSlot = -1;
2020-11-05 15:05:16 +00:00
#endif // BUTTON_ICONS
2020-04-26 20:49:24 +00:00
void
CFont::Initialise(void)
{
int slot;
slot = CTxdStore::AddTxdSlot("fonts");
#ifdef MORE_LANGUAGES
Slot = slot;
switch (LanguageSet)
{
case FONT_LANGSET_EFIGS:
default:
CTxdStore::LoadTxd(slot, "MODELS/FONTS.TXD");
break;
case FONT_LANGSET_POLISH:
CTxdStore::LoadTxd(slot, "MODELS/FONTS_P.TXD");
break;
case FONT_LANGSET_RUSSIAN:
CTxdStore::LoadTxd(slot, "MODELS/FONTS_R.TXD");
break;
case FONT_LANGSET_JAPANESE:
CTxdStore::LoadTxd(slot, "MODELS/FONTS_J.TXD");
break;
}
#else
CTxdStore::LoadTxd(slot, "MODELS/FONTS.TXD");
#endif
CTxdStore::AddRef(slot);
CTxdStore::PushCurrentTxd();
CTxdStore::SetCurrentTxd(slot);
2020-06-07 01:11:10 +00:00
Sprite[0].SetTexture("font2", "font2m");
2020-04-26 20:49:24 +00:00
#ifdef MORE_LANGUAGES
if (IsJapanese()) {
Sprite[1].SetTexture("FONTJAP", "FONTJAP_mask");
Sprite[3].SetTexture("FONTJAP", "FONTJAP_mask");
}
#endif // MORE_LANGUAGES
2020-06-07 01:11:10 +00:00
Sprite[1].SetTexture("font1", "font1m");
2020-04-26 20:49:24 +00:00
SetScale(1.0f, 1.0f);
SetSlantRefPoint(SCREEN_WIDTH, 0.0f);
SetSlant(0.0f);
2021-01-12 23:01:04 +00:00
SetColor(CRGBA(255, 255, 255, 0));
2020-04-26 20:49:24 +00:00
SetJustifyOff();
SetCentreOff();
SetWrapx(SCREEN_WIDTH);
SetCentreSize(SCREEN_WIDTH);
2020-04-26 20:49:24 +00:00
SetBackgroundOff();
2021-01-12 23:01:04 +00:00
SetBackgroundColor(CRGBA(128, 128, 128, 128));
2020-04-26 20:49:24 +00:00
SetBackGroundOnlyTextOff();
SetPropOn();
SetFontStyle(FONT_BANK);
SetRightJustifyWrap(0.0f);
SetAlphaFade(255.0f);
SetDropShadowPosition(0);
CTxdStore::PopCurrentTxd();
2020-11-05 15:05:16 +00:00
2021-02-10 06:57:51 +00:00
#if !defined(GAMEPAD_MENU) && defined(BUTTON_ICONS)
// loaded in CMenuManager with GAMEPAD_MENU defined
LoadButtons("MODELS/X360BTNS.TXD");
#endif
}
2020-11-05 15:05:16 +00:00
#ifdef BUTTON_ICONS
2021-02-10 06:57:51 +00:00
void
CFont::LoadButtons(const char *txdPath)
{
if (int file = CFileMgr::OpenFile(txdPath)) {
2020-11-07 18:54:38 +00:00
CFileMgr::CloseFile(file);
2021-02-10 06:57:51 +00:00
if (ButtonsSlot == -1)
ButtonsSlot = CTxdStore::AddTxdSlot("buttons");
else {
for (int i = 0; i < MAX_BUTTON_ICONS; i++)
ButtonSprite[i].Delete();
CTxdStore::RemoveTxd(ButtonsSlot);
}
CTxdStore::LoadTxd(ButtonsSlot, txdPath);
2020-11-07 18:54:38 +00:00
CTxdStore::AddRef(ButtonsSlot);
CTxdStore::PushCurrentTxd();
CTxdStore::SetCurrentTxd(ButtonsSlot);
2021-01-02 10:50:28 +00:00
ButtonSprite[BUTTON_UP].SetTexture("thumblyu");
ButtonSprite[BUTTON_DOWN].SetTexture("thumblyd");
ButtonSprite[BUTTON_LEFT].SetTexture("thumblxl");
ButtonSprite[BUTTON_RIGHT].SetTexture("thumblxr");
2020-11-07 18:54:38 +00:00
ButtonSprite[BUTTON_CROSS].SetTexture("cross");
ButtonSprite[BUTTON_CIRCLE].SetTexture("circle");
ButtonSprite[BUTTON_SQUARE].SetTexture("square");
ButtonSprite[BUTTON_TRIANGLE].SetTexture("triangle");
ButtonSprite[BUTTON_L1].SetTexture("l1");
ButtonSprite[BUTTON_L2].SetTexture("l2");
ButtonSprite[BUTTON_L3].SetTexture("l3");
ButtonSprite[BUTTON_R1].SetTexture("r1");
ButtonSprite[BUTTON_R2].SetTexture("r2");
ButtonSprite[BUTTON_R3].SetTexture("r3");
2021-02-10 06:57:51 +00:00
ButtonSprite[BUTTON_RSTICK_UP].SetTexture("thumbryu");
ButtonSprite[BUTTON_RSTICK_DOWN].SetTexture("thumbryd");
2021-01-02 10:50:28 +00:00
ButtonSprite[BUTTON_RSTICK_LEFT].SetTexture("thumbrxl");
ButtonSprite[BUTTON_RSTICK_RIGHT].SetTexture("thumbrxr");
2020-11-07 18:54:38 +00:00
CTxdStore::PopCurrentTxd();
}
2021-02-10 06:57:51 +00:00
else {
if (ButtonsSlot != -1) {
for (int i = 0; i < MAX_BUTTON_ICONS; i++)
ButtonSprite[i].Delete();
CTxdStore::RemoveTxdSlot(ButtonsSlot);
ButtonsSlot = -1;
}
}
2020-04-26 20:49:24 +00:00
}
2021-02-10 06:57:51 +00:00
#endif // BUTTON_ICONS
2020-04-26 20:49:24 +00:00
#ifdef MORE_LANGUAGES
void
CFont::ReloadFonts(uint8 set)
{
if (Slot != -1 && LanguageSet != set) {
Sprite[0].Delete();
Sprite[1].Delete();
if (IsJapanese())
2021-02-18 09:34:23 +00:00
Sprite[2].Delete();
2020-04-26 20:49:24 +00:00
CTxdStore::PushCurrentTxd();
CTxdStore::RemoveTxd(Slot);
switch (set)
{
case FONT_LANGSET_EFIGS:
default:
CTxdStore::LoadTxd(Slot, "MODELS/FONTS.TXD");
break;
case FONT_LANGSET_POLISH:
CTxdStore::LoadTxd(Slot, "MODELS/FONTS_P.TXD");
break;
case FONT_LANGSET_RUSSIAN:
CTxdStore::LoadTxd(Slot, "MODELS/FONTS_R.TXD");
break;
case FONT_LANGSET_JAPANESE:
CTxdStore::LoadTxd(Slot, "MODELS/FONTS_J.TXD");
break;
}
CTxdStore::SetCurrentTxd(Slot);
Sprite[0].SetTexture("font2", "font2_mask");
if (set == FONT_LANGSET_JAPANESE) {
2021-02-18 09:34:23 +00:00
Sprite[2].SetTexture("FONTJAP", "FONTJAP_mask");
2020-04-26 20:49:24 +00:00
}
2021-02-18 09:34:23 +00:00
Sprite[1].SetTexture("font1", "font1_mask");
2020-04-26 20:49:24 +00:00
CTxdStore::PopCurrentTxd();
}
LanguageSet = set;
}
#endif
void
CFont::Shutdown(void)
{
2020-11-05 15:05:16 +00:00
#ifdef BUTTON_ICONS
2020-11-07 18:54:38 +00:00
if (ButtonsSlot != -1) {
for (int i = 0; i < MAX_BUTTON_ICONS; i++)
ButtonSprite[i].Delete();
CTxdStore::RemoveTxdSlot(ButtonsSlot);
2021-02-10 06:57:51 +00:00
ButtonsSlot = -1;
2020-11-07 18:54:38 +00:00
}
2020-11-05 15:05:16 +00:00
#endif
2020-04-26 20:49:24 +00:00
Sprite[0].Delete();
Sprite[1].Delete();
#ifdef MORE_LANGUAGES
if (IsJapanese())
Sprite[3].Delete();
CTxdStore::RemoveTxdSlot(Slot);
Slot = -1;
#else
CTxdStore::RemoveTxdSlot(CTxdStore::FindTxdSlot("fonts"));
#endif
}
void
CFont::InitPerFrame(void)
{
2020-06-07 07:36:37 +00:00
RenderState.style = -1;
2020-06-07 01:11:10 +00:00
Details.anonymous_25 = 0;
2020-06-07 07:36:37 +00:00
FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf;
2020-04-26 20:49:24 +00:00
SetDropShadowPosition(0);
2021-01-16 14:06:11 +00:00
NewLine = false;
2020-11-05 15:05:16 +00:00
#ifdef BUTTON_ICONS
PS2Symbol = BUTTON_NONE;
#endif
2020-04-26 20:49:24 +00:00
}
2020-11-05 15:05:16 +00:00
#ifdef BUTTON_ICONS
void
CFont::DrawButton(float x, float y)
{
if (x <= 0.0f || x > SCREEN_WIDTH || y <= 0.0f || y > SCREEN_HEIGHT)
return;
if (PS2Symbol != BUTTON_NONE) {
CRect rect;
rect.left = x;
2021-01-30 18:46:37 +00:00
rect.top = RenderState.scaleY + RenderState.scaleY + y;
rect.right = RenderState.scaleY * 17.0f + x;
rect.bottom = RenderState.scaleY * 19.0f + y;
2020-11-05 15:05:16 +00:00
int vertexAlphaState;
2021-01-02 10:50:28 +00:00
void *raster;
2020-11-05 15:05:16 +00:00
RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &vertexAlphaState);
2021-01-02 10:50:28 +00:00
RwRenderStateGet(rwRENDERSTATETEXTURERASTER, &raster);
2020-11-05 15:05:16 +00:00
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
2021-01-30 18:46:37 +00:00
if (RenderState.bIsShadow)
ButtonSprite[PS2Symbol].Draw(rect, RenderState.color);
else
ButtonSprite[PS2Symbol].Draw(rect, CRGBA(255, 255, 255, RenderState.color.a));
2021-01-02 10:50:28 +00:00
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, raster);
2020-11-05 15:05:16 +00:00
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)vertexAlphaState);
}
2020-04-26 20:49:24 +00:00
}
2020-11-05 15:05:16 +00:00
#endif
2020-04-26 20:49:24 +00:00
void
CFont::PrintChar(float x, float y, wchar c)
{
2020-06-07 01:11:10 +00:00
bool bDontPrint = false;
2020-04-26 20:49:24 +00:00
if(x <= 0.0f || x > SCREEN_WIDTH ||
y <= 0.0f || y > SCREEN_HEIGHT) // BUG: game uses SCREENW again
return;
2020-06-07 01:11:10 +00:00
bDontPrint = c == '\0';
2020-04-26 20:49:24 +00:00
float w = GetCharacterWidth(c) / 32.0f;
2021-01-10 20:37:11 +00:00
if (Details.bFontHalfTexture && c == 208)
2020-06-07 01:11:10 +00:00
c = '\0';
2020-04-26 20:49:24 +00:00
float xoff = c % 16;
float yoff = c / 16;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont()) {
w = 21.0f;
xoff = (float)(c % 48);
yoff = c / 48;
}
#endif
2021-01-09 14:55:45 +00:00
if(RenderState.style == FONT_BANK || RenderState.style == FONT_STANDARD){
2020-06-07 01:11:10 +00:00
if (bDontPrint) return;
2020-06-07 07:36:37 +00:00
if (RenderState.slant == 0.0f) {
2020-12-08 00:22:02 +00:00
#ifdef FIX_BUGS
if (c < 192) {
#else
2020-06-07 07:36:37 +00:00
if (c < 193) {
2020-12-08 00:22:02 +00:00
#endif
2020-06-07 07:36:37 +00:00
CSprite2d::AddToBuffer(
CRect(x, y,
x + 32.0f * RenderState.scaleX * 1.0f,
y + 40.0f * RenderState.scaleY * 0.5f),
RenderState.color,
xoff / 16.0f, yoff / 12.8f + 0.0021f,
(xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f,
xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.0021f,
(xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.0021f);
} else {
CSprite2d::AddToBuffer(
CRect(x, y,
x + 32.0f * RenderState.scaleX * 1.0f,
y + 33.0f * RenderState.scaleY * 0.5f),
RenderState.color,
2020-12-07 20:56:22 +00:00
xoff / 16.0f, yoff / 12.8f + 0.0021f,
(xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f,
xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.017f,
2020-06-07 07:36:37 +00:00
(xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.017f);
}
} else
CSprite2d::AddToBuffer(
CRect(x, y,
x + 32.0f * RenderState.scaleX * 1.0f,
y + 40.0f * RenderState.scaleY * 0.5f),
RenderState.color,
xoff / 16.0f, yoff / 12.8f + 0.00055f,
(xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f + 0.01f,
xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.009f,
(xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.0021f + 0.01f);
2020-04-26 20:49:24 +00:00
#ifdef MORE_LANGUAGES
2021-02-18 09:34:23 +00:00
/*}else if (IsJapaneseFont()) {
2020-04-26 20:49:24 +00:00
if (Details.dropShadowPosition != 0) {
CSprite2d::AddSpriteToBank(Details.bank + Details.style, // BUG: game doesn't add bank
CRect(x + SCREEN_SCALE_X(Details.dropShadowPosition),
y + SCREEN_SCALE_Y(Details.dropShadowPosition),
x + SCREEN_SCALE_X(Details.dropShadowPosition) + 32.0f * Details.scaleX * 1.0f,
y + SCREEN_SCALE_Y(Details.dropShadowPosition) + 40.0f * Details.scaleY / 2.75f),
Details.dropColor,
xoff * w / 1024.0f, yoff / 25.6f,
xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, yoff / 25.6f,
xoff * w / 1024.0f, (yoff + 1.0f) / 25.6f,
xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, (yoff + 1.0f) / 25.6f - 0.0001f);
}
CSprite2d::AddSpriteToBank(Details.bank + Details.style, // BUG: game doesn't add bank
CRect(x, y,
x + 32.0f * Details.scaleX * 1.0f,
y + 40.0f * Details.scaleY / 2.75f),
Details.color,
xoff * w / 1024.0f, yoff / 25.6f,
xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, yoff / 25.6f,
xoff * w / 1024.0f, (yoff + 1.0f) / 25.6f - 0.002f,
2021-02-18 09:34:23 +00:00
xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, (yoff + 1.0f) / 25.6f - 0.0001f);*/
2020-04-26 20:49:24 +00:00
#endif
2020-06-07 07:36:37 +00:00
} else {
2020-06-07 01:11:10 +00:00
if (bDontPrint) return;
2020-06-07 07:36:37 +00:00
CSprite2d::AddToBuffer(
CRect(x, y,
x + 32.0f * RenderState.scaleX * w,
2020-06-07 07:43:33 +00:00
y + 32.0f * RenderState.scaleY * 0.5f),
2020-06-07 07:36:37 +00:00
RenderState.color,
xoff / 16.0f, yoff / 16.0f,
(xoff + w) / 16.0f, yoff / 16.0f,
xoff / 16.0f, (yoff + 1.0f) / 16.0f,
(xoff + w) / 16.0f - 0.0001f, (yoff + 1.0f) / 16.0f - 0.0001f);
2020-06-07 01:11:10 +00:00
}
2020-04-26 20:49:24 +00:00
}
#ifdef MORE_LANGUAGES
bool CFont::IsJapanesePunctuation(wchar *str)
{
return (*str == 0xE7 || *str == 0x124 || *str == 0x126 || *str == 0x128 || *str == 0x104 || *str == ',' || *str == '>' || *str == '!' || *str == 0x99 || *str == '?' || *str == ':');
}
bool CFont::IsAnsiCharacter(wchar *s)
{
if (*s >= 'A' && *s <= 'Z')
return true;
if (*s >= 'a' && *s <= 'z')
return true;
if (*s >= '0' && *s <= ':')
return true;
if (*s == '(' || *s == ')')
return true;
if (*s == 'D' || *s == '$')
return true;
return false;
}
#endif
2021-01-16 14:06:11 +00:00
void
CFont::RenderFontBuffer()
{
if (FontRenderStatePointer.pRenderState == (CFontRenderState*)FontRenderStateBuf) return;
float textPosX;
float textPosY;
CRGBA color;
bool bBold = false;
bool bFlash = false;
Sprite[RenderState.style].SetRenderState();
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RenderState = *(CFontRenderState*)&FontRenderStateBuf[0];
textPosX = RenderState.fTextPosX;
textPosY = RenderState.fTextPosY;
color = RenderState.color;
tFontRenderStatePointer pRenderStateBufPointer;
pRenderStateBufPointer.pRenderState = (CFontRenderState*)&FontRenderStateBuf[0];
for (++pRenderStateBufPointer.pRenderState; pRenderStateBufPointer.pStr < FontRenderStatePointer.pStr; pRenderStateBufPointer.pStr++) {
if (*pRenderStateBufPointer.pStr == '\0') {
tFontRenderStatePointer tmpPointer = pRenderStateBufPointer;
tmpPointer.pStr++;
tmpPointer.Align();
if (tmpPointer.pStr >= FontRenderStatePointer.pStr)
break;
RenderState = *(tmpPointer.pRenderState++);
pRenderStateBufPointer = tmpPointer;
textPosX = RenderState.fTextPosX;
textPosY = RenderState.fTextPosY;
color = RenderState.color;
}
if (*pRenderStateBufPointer.pStr == '~') {
#ifdef BUTTON_ICONS
PS2Symbol = BUTTON_NONE;
#endif
pRenderStateBufPointer.pStr = ParseToken(pRenderStateBufPointer.pStr, color, bFlash, bBold);
#ifdef BUTTON_ICONS
if(PS2Symbol != BUTTON_NONE) {
DrawButton(textPosX, textPosY);
2021-01-30 18:46:37 +00:00
textPosX += RenderState.scaleY * 17.0f;
2021-01-16 14:06:11 +00:00
PS2Symbol = BUTTON_NONE;
}
#endif
if (bFlash) {
if (CTimer::GetTimeInMilliseconds() - Details.nFlashTimer > 300) {
Details.bFlashState = !Details.bFlashState;
Details.nFlashTimer = CTimer::GetTimeInMilliseconds();
}
Details.color.alpha = Details.bFlashState ? 0 : 255;
}
if (!RenderState.bIsShadow)
RenderState.color = color;
}
wchar c = *pRenderStateBufPointer.pStr;
c -= ' ';
if (RenderState.bFontHalfTexture)
c = FindNewCharacter(c);
else if (c > 155)
c = '\0';
if (RenderState.slant != 0.0f)
textPosY = (RenderState.slantRefX - textPosX) * RenderState.slant + RenderState.slantRefY;
PrintChar(textPosX, textPosY, c);
if (bBold) {
PrintChar(textPosX + 1.0f, textPosY, c);
PrintChar(textPosX + 2.0f, textPosY, c);
textPosX += 2.0f;
}
#ifdef FIX_BUGS
// PS2 uses different chars for some symbols
if (!RenderState.bFontHalfTexture && c == 30) c = 61; // wanted star
#endif
textPosX += RenderState.scaleX * GetCharacterWidth(c);
if (c == '\0')
textPosX += RenderState.fExtraSpace;
}
CSprite2d::RenderVertexBuffer();
FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf;
}
2021-02-18 09:34:23 +00:00
#if 0 //def MORE_LANGUAGES
2021-01-16 14:06:11 +00:00
bool
CFont::PrintString(float x, float y, wchar *start, wchar *&end, float spwidth, float japX)
{
wchar *s, c, unused;
if (IsJapanese()) {
float jx = 0.0f;
for (s = start; s < end; s++) {
if (*s == JAP_TERMINATION || *s == '~')
s = ParseToken(s, &unused, true);
if (NewLine) {
NewLine = false;
break;
}
jx += GetCharacterSize(*s - ' ');
}
s = start;
if (Details.centre)
x = japX - jx / 2.0f;
else if (Details.rightJustify)
x = japX - jx;
}
for (s = start; s < end; s++) {
if (*s == '~' || (IsJapanese() && *s == JAP_TERMINATION))
s = ParseToken(s, &unused);
if (NewLine && IsJapanese()) {
NewLine = false;
end = s;
return true;
}
c = *s - ' ';
if (Details.slant != 0.0f && !IsJapanese())
y = (Details.slantRefX - x) * Details.slant + Details.slantRefY;
PrintChar(x, y, c);
x += GetCharacterSize(c);
if (c == 0 && (!NewLine || !IsJapanese())) // space
x += spwidth;
}
return false;
}
#else
void
CFont::PrintString(float x, float y, uint32, wchar *start, wchar *end, float spwidth)
{
wchar *s;
if (RenderState.style != Details.style) {
RenderFontBuffer();
RenderState.style = Details.style;
}
float dropShadowPosition = Details.dropShadowPosition;
if (dropShadowPosition != 0.0f && (Details.style == FONT_BANK || Details.style == FONT_STANDARD)) {
CRGBA color = Details.color;
Details.color = Details.dropColor;
Details.dropShadowPosition = 0;
Details.bIsShadow = true;
if (Details.slant != 0.0f) {
Details.slantRefX += SCREEN_SCALE_X(dropShadowPosition);
Details.slantRefY += SCREEN_SCALE_Y(dropShadowPosition);
PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth);
Details.slantRefX -= SCREEN_SCALE_X(dropShadowPosition);
Details.slantRefY -= SCREEN_SCALE_Y(dropShadowPosition);
} else {
PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth);
}
Details.color = color;
Details.dropShadowPosition = dropShadowPosition;
Details.bIsShadow = false;
}
if (FontRenderStatePointer.pStr >= (wchar*)&FontRenderStateBuf[ARRAY_SIZE(FontRenderStateBuf)] - (end - start + 26)) // why 26?
RenderFontBuffer();
CFontRenderState *pRenderState = FontRenderStatePointer.pRenderState;
pRenderState->fTextPosX = x;
pRenderState->fTextPosY = y;
pRenderState->scaleX = Details.scaleX;
pRenderState->scaleY = Details.scaleY;
pRenderState->color = Details.color;
pRenderState->fExtraSpace = spwidth;
pRenderState->slant = Details.slant;
pRenderState->slantRefX = Details.slantRefX;
pRenderState->slantRefY = Details.slantRefY;
pRenderState->bFontHalfTexture = Details.bFontHalfTexture;
pRenderState->proportional = Details.proportional;
pRenderState->style = Details.style;
pRenderState->bIsShadow = Details.bIsShadow;
FontRenderStatePointer.pRenderState++;
for(s = start; s < end;){
if (*s == '~') {
for (wchar *i = ParseToken(s); s != i; FontRenderStatePointer.pStr++) {
*FontRenderStatePointer.pStr = *(s++);
}
if (Details.bFlash) {
if (CTimer::GetTimeInMilliseconds() - Details.nFlashTimer > 300) {
Details.bFlashState = !Details.bFlashState;
Details.nFlashTimer = CTimer::GetTimeInMilliseconds();
}
Details.color.a = Details.bFlashState ? 0 : 255;
}
} else
*(FontRenderStatePointer.pStr++) = *(s++);
}
*(FontRenderStatePointer.pStr++) = '\0';
FontRenderStatePointer.Align();
}
#endif
void
CFont::PrintStringFromBottom(float x, float y, wchar *str)
{
y -= (32.0f * Details.scaleY / 2.0f + 2.0f * Details.scaleY) * GetNumberLines(x, y, str);
2021-01-20 12:23:03 +00:00
if (Details.slant != 0.0f)
2021-01-16 14:06:11 +00:00
y -= ((Details.slantRefX - x) * Details.slant + Details.slantRefY);
PrintString(x, y, str);
}
2020-04-26 20:49:24 +00:00
void
CFont::PrintString(float xstart, float ystart, wchar *s)
{
CRect rect;
int numSpaces;
float lineLength;
float x, y;
bool first;
wchar *start, *t;
2020-10-20 19:19:05 +00:00
Details.bFlash = false;
2020-04-26 20:49:24 +00:00
if(*s == '*')
return;
2020-10-20 19:19:05 +00:00
Details.anonymous_25++;
2020-04-26 20:49:24 +00:00
if(Details.background){
2020-10-20 19:19:05 +00:00
RenderState.color = Details.color;
2020-04-26 20:49:24 +00:00
GetNumberLines(xstart, ystart, s); // BUG: result not used
GetTextRect(&rect, xstart, ystart, s);
CSprite2d::DrawRect(rect, Details.backgroundColor);
}
lineLength = 0.0f;
numSpaces = 0;
first = true;
if(Details.centre || Details.rightJustify)
x = 0.0f;
else
x = xstart;
y = ystart;
start = s;
// This is super ugly, I blame R*
for(;;){
for(;;){
for(;;){
if(*s == '\0')
return;
float xend = Details.centre ? Details.centreSize :
Details.rightJustify ? xstart - Details.rightJustifyWrap :
Details.wrapX;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont())
xend -= SCREEN_SCALE_X(21.0f * 2.0f);
#endif
if(x + GetStringWidth(s) > xend && !first){
#ifdef MORE_LANGUAGES
if (IsJapanese() && IsJapanesePunctuation(s))
s--;
#endif
// flush line
float spaceWidth = !Details.justify || Details.centre ? 0.0f :
(Details.wrapX - lineLength) / numSpaces;
float xleft = Details.centre ? xstart - x/2 :
Details.rightJustify ? xstart - x :
xstart;
2021-02-18 09:34:23 +00:00
#if 0//def MORE_LANGUAGES
2020-04-26 20:49:24 +00:00
PrintString(xleft, y, start, s, spaceWidth, xstart);
2020-06-07 07:36:37 +00:00
#else
PrintString(xleft, y, Details.anonymous_25, start, s, spaceWidth);
2020-04-26 20:49:24 +00:00
#endif
// reset things
lineLength = 0.0f;
numSpaces = 0;
first = true;
if(Details.centre || Details.rightJustify)
x = 0.0f;
else
x = xstart;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont())
2021-01-12 23:01:04 +00:00
y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY;
2020-04-26 20:49:24 +00:00
else
#endif
2021-01-12 23:01:04 +00:00
y += 32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY;
2020-04-26 20:49:24 +00:00
start = s;
}else
break;
}
// advance by one word
t = GetNextSpace(s);
if(t[0] == '\0' ||
t[0] == ' ' && t[1] == '\0')
break;
if(!first)
numSpaces++;
first = false;
x += GetStringWidth(s) + GetCharacterSize(*t - ' ');
#ifdef MORE_LANGUAGES
if (IsJapaneseFont() && IsAnsiCharacter(s))
x += 21.0f;
#endif
lineLength = x;
s = t+1;
2021-02-18 09:34:23 +00:00
#if 0 //def MORE_LANGUAGES
2020-04-26 20:49:24 +00:00
if (IsJapaneseFont() && !*s) {
x += GetStringWidth(s);
if (IsAnsiCharacter(s))
x += 21.0f;
float xleft = Details.centre ? xstart - x / 2 :
Details.rightJustify ? xstart - x :
xstart;
if (PrintString(xleft, y, start, s, 0.0f, xstart))
{
start = s;
if (!Details.centre && !Details.rightJustify)
x = xstart;
else
x = 0.0f;
2021-01-12 23:01:04 +00:00
y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY;
2020-04-26 20:49:24 +00:00
numSpaces = 0;
first = true;
lineLength = 0.0f;
}
}
#endif
}
// print rest
if(t[0] == ' ' && t[1] == '\0')
t[0] = '\0';
x += GetStringWidth(s);
s = t;
float xleft = Details.centre ? xstart - x/2 :
Details.rightJustify ? xstart - x :
xstart;
2021-02-18 09:34:23 +00:00
#if 0 //def MORE_LANGUAGES
2020-04-26 20:49:24 +00:00
if (PrintString(xleft, y, start, s, 0.0f, xstart) && IsJapaneseFont()) {
start = s;
if (!Details.centre && !Details.rightJustify)
x = xstart;
else
x = 0.0f;
2021-01-12 23:01:04 +00:00
y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY;
2020-04-26 20:49:24 +00:00
numSpaces = 0;
first = true;
lineLength = 0.0f;
}
#else
2020-06-07 07:36:37 +00:00
PrintString(xleft, y, Details.anonymous_25, start, s, 0.0f);
2020-04-26 20:49:24 +00:00
#endif
}
}
int
CFont::GetNumberLines(float xstart, float ystart, wchar *s)
{
int n;
float x, y;
wchar *t;
n = 0;
2021-02-18 09:34:23 +00:00
#if 0//def MORE_LANGUAGES
2020-04-26 20:49:24 +00:00
bool bSomeJapBool = false;
if (IsJapanese()) {
t = s;
wchar unused;
while (*t) {
if (*t == JAP_TERMINATION || *t == '~')
t = ParseToken(t, &unused, true);
if (NewLine) {
n++;
NewLine = false;
bSomeJapBool = true;
}
t++;
}
}
if (bSomeJapBool) n--;
#endif
if(Details.centre || Details.rightJustify)
x = 0.0f;
else
x = xstart;
y = ystart;
while(*s){
#ifdef FIX_BUGS
float f = Details.centre ? Details.centreSize :
Details.rightJustify ? xstart - Details.rightJustifyWrap :
Details.wrapX;
#else
2020-04-26 20:49:24 +00:00
float f = (Details.centre ? Details.centreSize : Details.wrapX);
#endif
2020-04-26 20:49:24 +00:00
#ifdef MORE_LANGUAGES
if (IsJapaneseFont())
f -= SCREEN_SCALE_X(21.0f * 2.0f);
#endif
if(x + GetStringWidth(s) > f){
#ifdef MORE_LANGUAGES
if (IsJapanese())
{
if (IsJapanesePunctuation(s))
s--;
}
#endif
// reached end of line
if(Details.centre || Details.rightJustify)
x = 0.0f;
else
x = xstart;
n++;
// Why even?
#ifdef MORE_LANGUAGES
if (IsJapanese())
2021-01-12 23:01:04 +00:00
y += 32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY;
2020-04-26 20:49:24 +00:00
else
#endif
2021-01-12 23:01:04 +00:00
y += 32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY;
2020-04-26 20:49:24 +00:00
}else{
// still space in current line
t = GetNextSpace(s);
if(*t == '\0'){
// end of string
x += GetStringWidth(s);
#ifdef MORE_LANGUAGES
if (IsJapanese() && IsAnsiCharacter(s))
x += 21.0f;
#endif
n++;
s = t;
}else{
x += GetStringWidth(s);
#ifdef MORE_LANGUAGES
if (IsJapanese() && IsAnsiCharacter(s))
x += 21.0f;
#endif
s = t+1;
x += GetCharacterSize(*t - ' ');
#ifdef MORE_LANGUAGES
if (IsJapanese() && !*s)
n++;
#endif
}
}
}
return n;
}
void
CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s)
{
int numLines;
float x, y;
int16 maxlength;
wchar *t;
maxlength = 0;
numLines = 0;
#ifdef MORE_LANGUAGES
if (IsJapanese()) {
numLines = GetNumberLines(xstart, ystart, s);
}else{
#endif
if(Details.centre || Details.rightJustify)
x = 0.0f;
else
x = xstart;
y = ystart;
#ifdef FIX_BUGS
float xEnd = Details.centre ? Details.centreSize :
Details.rightJustify ? xstart - Details.rightJustifyWrap :
Details.wrapX;
#else
float xEnd = (Details.centre ? Details.centreSize : Details.wrapX);
#endif
2020-04-26 20:49:24 +00:00
while(*s){
if(x + GetStringWidth(s) > xEnd){
2020-04-26 20:49:24 +00:00
// reached end of line
if(x > maxlength)
maxlength = x;
if(Details.centre || Details.rightJustify)
x = 0.0f;
else
x = xstart;
numLines++;
2021-01-12 23:01:04 +00:00
y += 32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY;
2020-04-26 20:49:24 +00:00
}else{
// still space in current line
t = GetNextSpace(s);
if(*t == '\0'){
// end of string
x += GetStringWidth(s);
if(x > maxlength)
maxlength = x;
numLines++;
s = t;
}else{
x += GetStringWidth(s);
x += GetCharacterSize(*t - ' ');
s = t+1;
}
}
}
#ifdef MORE_LANGUAGES
}
#endif
if(Details.centre){
if(Details.backgroundOnlyText){
rect->left = xstart - maxlength/2 - 4.0f;
rect->right = xstart + maxlength/2 + 4.0f;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont()) {
2021-01-12 23:01:04 +00:00
rect->bottom = (32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY) * numLines + ystart + (4.0f / 2.75f);
2020-04-26 20:49:24 +00:00
rect->top = ystart - (4.0f / 2.75f);
} else {
#endif
2021-01-12 23:01:04 +00:00
rect->bottom = (32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f;
2020-04-26 20:49:24 +00:00
rect->top = ystart - 2.0f;
#ifdef MORE_LANGUAGES
}
#endif
}else{
rect->left = xstart - Details.centreSize*0.5f - 4.0f;
rect->right = xstart + Details.centreSize*0.5f + 4.0f;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont()) {
2021-01-12 23:01:04 +00:00
rect->bottom = (32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY) * numLines + ystart + (4.0f / 2.75f);
2020-04-26 20:49:24 +00:00
rect->top = ystart - (4.0f / 2.75f);
} else {
#endif
2021-01-12 23:01:04 +00:00
rect->bottom = (32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f;
2020-04-26 20:49:24 +00:00
rect->top = ystart - 2.0f;
#ifdef MORE_LANGUAGES
}
#endif
}
}else{
rect->left = xstart - 4.0f;
rect->right = Details.wrapX;
// WTF?
rect->bottom = ystart - 4.0f + 4.0f;
#ifdef MORE_LANGUAGES
if (IsJapaneseFont())
2021-01-12 23:01:04 +00:00
rect->top = (32.0f * Details.scaleY / 2.75f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f + (4.0f / 2.75f);
2020-04-26 20:49:24 +00:00
else
#endif
2021-01-12 23:01:04 +00:00
rect->top = (32.0f * Details.scaleY * 0.5f + 2.0f * Details.scaleY) * numLines + ystart + 2.0f + 2.0f;
2020-04-26 20:49:24 +00:00
}
}
2021-01-16 14:06:11 +00:00
float
CFont::GetCharacterWidth(wchar c)
2020-04-26 20:49:24 +00:00
{
2021-01-16 14:06:11 +00:00
#ifdef MORE_LANGUAGES
2020-04-26 20:49:24 +00:00
if (IsJapanese()) {
2021-02-18 09:34:23 +00:00
if (!RenderState.proportional)
2021-01-16 14:06:11 +00:00
return Size[0][Details.style][192];
2021-02-18 09:34:23 +00:00
if (c <= 94 || Details.style == FONT_HEADING || RenderState.style == FONT_BANK) {
switch (RenderState.style)
2021-01-16 14:06:11 +00:00
{
case FONT_JAPANESE:
return Size_jp[c];
default:
2021-02-18 09:34:23 +00:00
return Size[0][RenderState.style][c];
2020-04-26 20:49:24 +00:00
}
}
2021-02-18 09:34:23 +00:00
switch (RenderState.style)
2021-01-16 14:06:11 +00:00
{
case FONT_JAPANESE:
return 29.4f;
case FONT_BANK:
return 10.0f;
default:
2021-02-18 09:34:23 +00:00
return Size[0][RenderState.style][c];
2020-04-26 20:49:24 +00:00
}
}
2021-02-18 09:34:23 +00:00
else if (RenderState.proportional)
return Size[LanguageSet][RenderState.style][c];
2020-04-26 20:49:24 +00:00
else
2021-02-18 09:34:23 +00:00
return Size[LanguageSet][RenderState.style][209];
2020-04-26 20:49:24 +00:00
#else
2020-12-28 12:29:21 +00:00
2021-01-10 20:37:11 +00:00
if (RenderState.proportional)
return Size[RenderState.style][c];
2020-04-26 20:49:24 +00:00
else
2021-01-10 20:37:11 +00:00
return Size[RenderState.style][209];
2020-04-26 20:49:24 +00:00
#endif // MORE_LANGUAGES
}
float
CFont::GetCharacterSize(wchar c)
{
#ifdef MORE_LANGUAGES
if (IsJapanese())
{
if (!Details.proportional)
2020-06-07 01:11:10 +00:00
return Size[0][Details.style][209] * Details.scaleX;
2020-04-26 20:49:24 +00:00
if (c <= 94 || Details.style == FONT_HEADING || Details.style == FONT_BANK) {
switch (Details.style)
{
case FONT_JAPANESE:
return Size_jp[c] * Details.scaleX;
default:
return Size[0][Details.style][c] * Details.scaleX;
}
}
switch (Details.style)
{
case FONT_JAPANESE:
return 29.4f * Details.scaleX;
case FONT_BANK:
return 10.0f * Details.scaleX;
default:
return Size[0][Details.style][c] * Details.scaleX;
}
}
else
2021-02-18 09:34:23 +00:00
{
if (!Details.bFontHalfTexture && c == 30) c = 61; // wanted star
if (Details.bFontHalfTexture)
c = FindNewCharacter(c);
if (Details.proportional)
return Size[LanguageSet][Details.style][c] * Details.scaleX;
else
return Size[LanguageSet][Details.style][209] * Details.scaleX;
}
2020-04-26 20:49:24 +00:00
#else
2020-12-28 12:29:21 +00:00
#ifdef FIX_BUGS
// PS2 don't call FindNewCharacter in here at all, and also uses different chars for some symbols
if (!Details.bFontHalfTexture && c == 30) c = 61; // wanted star
#endif
2020-06-07 01:11:10 +00:00
if (Details.bFontHalfTexture)
c = FindNewCharacter(c);
2020-04-26 20:49:24 +00:00
if (Details.proportional)
return Size[Details.style][c] * Details.scaleX;
else
2020-06-07 01:11:10 +00:00
return Size[Details.style][209] * Details.scaleX;
2020-04-26 20:49:24 +00:00
#endif // MORE_LANGUAGES
}
float
CFont::GetStringWidth(wchar *s, bool spaces)
{
float w;
w = 0.0f;
#ifdef MORE_LANGUAGES
if (IsJapanese())
{
do
{
if ((*s != ' ' || spaces) && *s != '\0') {
do {
while (*s == '~' || *s == JAP_TERMINATION) {
s++;
2020-11-05 15:05:16 +00:00
#ifdef BUTTON_ICONS
switch (*s) {
case 'U':
case 'D':
case '<':
case '>':
case 'X':
case 'O':
case 'Q':
case 'T':
case 'K':
case 'M':
case 'A':
case 'J':
case 'V':
case 'C':
2021-01-02 10:50:28 +00:00
case '(':
case ')':
2020-11-05 15:05:16 +00:00
w += 17.0f * Details.scaleY;
break;
default:
break;
}
#endif
2020-04-26 20:49:24 +00:00
while (!(*s == '~' || *s == JAP_TERMINATION)) s++;
s++;
}
w += GetCharacterSize(*s - ' ');
++s;
} while (*s == '~' || *s == JAP_TERMINATION);
}
} while (IsAnsiCharacter(s));
} else
#endif
{
2020-06-07 07:43:33 +00:00
for (wchar c = *s; (c != ' ' || spaces) && c != '\0'; c = *(++s)) {
if (c == '~') {
2020-04-26 20:49:24 +00:00
s++;
2020-11-05 15:05:16 +00:00
#ifdef BUTTON_ICONS
switch (*s) {
case 'U':
case 'D':
case '<':
case '>':
case 'X':
case 'O':
case 'Q':
case 'T':
case 'K':
case 'M':
case 'A':
case 'J':
case 'V':
case 'C':
2021-01-02 10:50:28 +00:00
case '(':
case ')':
2020-11-05 15:05:16 +00:00
w += 17.0f * Details.scaleY;
break;
default:
break;
}
#endif
2020-06-07 07:43:33 +00:00
while (*s != '~') {
s++;
}
}
else {
w += GetCharacterSize(c - ' ');
2020-04-26 20:49:24 +00:00
}
}
}
return w;
}
#ifdef MORE_LANGUAGES
float
CFont::GetStringWidth_Jap(wchar* s)
{
float w;
w = 0.0f;
for (; *s != '\0';) {
do {
while (*s == '~' || *s == JAP_TERMINATION) {
s++;
while (!(*s == '~' || *s == JAP_TERMINATION)) s++;
s++;
}
w += GetCharacterSize(*s - ' ');
++s;
} while (*s == '~' || *s == JAP_TERMINATION);
}
return w;
}
#endif
wchar*
CFont::GetNextSpace(wchar *s)
{
#ifdef MORE_LANGUAGES
if (IsJapanese()) {
do
{
if (*s != ' ' && *s != '\0') {
do {
while (*s == '~' || *s == JAP_TERMINATION) {
s++;
while (!(*s == '~' || *s == JAP_TERMINATION)) s++;
s++;
}
++s;
} while (*s == '~' || *s == JAP_TERMINATION);
}
} while (IsAnsiCharacter(s));
} else
#endif
{
for(; *s != ' ' && *s != '\0'; s++)
if(*s == '~'){
s++;
while(*s != '~') s++;
}
}
return s;
}
2021-01-16 14:06:11 +00:00
wchar*
CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold)
{
Details.anonymous_23 = false;
wchar *s = str + 1;
if (Details.color.r || Details.color.g || Details.color.b)
{
switch (*s)
{
case 'B':
bold = !bold;
break;
case 'b':
color.r = 27;
color.g = 89;
color.b = 130;
break;
case 'f':
flash = !flash;
break;
case 'g':
color.r = 255;
color.g = 150;
color.b = 225;
break;
case 'h':
color.r = 225;
color.g = 225;
color.b = 225;
break;
case 'l':
color.r = 0;
color.g = 0;
color.b = 0;
break;
case 'o':
color.r = 229;
color.g = 125;
color.b = 126;
break;
case 'p':
color.r = 168;
color.g = 110;
color.b = 252;
break;
case 'q':
color.r = 199;
color.g = 144;
color.b = 203;
break;
case 'r':
color.r = 255;
color.g = 150;
color.b = 225;
break;
case 't':
color.r = 86;
color.g = 212;
color.b = 146;
break;
case 'w':
color.r = 175;
color.g = 175;
color.b = 175;
break;
#ifdef FIX_BUGS
case 'x':
color.r = 0;
color.g = 255;
color.b = 255;
break;
#else
case 'x':
color.r = 132;
color.g = 146;
color.b = 197;
break;
#endif
case 'y':
color.r = 255;
color.g = 227;
color.b = 79;
break;
#ifdef BUTTON_ICONS
case 'U': PS2Symbol = BUTTON_UP; break;
case 'D': PS2Symbol = BUTTON_DOWN; break;
case '<': PS2Symbol = BUTTON_LEFT; break;
case '>': PS2Symbol = BUTTON_RIGHT; break;
case 'X': PS2Symbol = BUTTON_CROSS; break;
case 'O': PS2Symbol = BUTTON_CIRCLE; break;
case 'Q': PS2Symbol = BUTTON_SQUARE; break;
case 'T': PS2Symbol = BUTTON_TRIANGLE; break;
case 'K': PS2Symbol = BUTTON_L1; break;
case 'M': PS2Symbol = BUTTON_L2; break;
case 'A': PS2Symbol = BUTTON_L3; break;
case 'J': PS2Symbol = BUTTON_R1; break;
case 'V': PS2Symbol = BUTTON_R2; break;
case 'C': PS2Symbol = BUTTON_R3; break;
2021-02-10 06:57:51 +00:00
case 'H': PS2Symbol = BUTTON_RSTICK_UP; break;
case 'L': PS2Symbol = BUTTON_RSTICK_DOWN; break;
2021-01-16 14:06:11 +00:00
case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break;
case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break;
#endif
default:
break;
}
}
while (*s != '~')
++s;
if (*(++s) == '~')
s = ParseToken(s, color, flash, bold);
return s;
}
2021-02-18 09:34:23 +00:00
#if 0//def MORE_LANGUAGES
2020-04-26 20:49:24 +00:00
wchar*
2020-06-07 02:12:01 +00:00
CFont::ParseToken(wchar *s, bool japShit)
2020-04-26 20:49:24 +00:00
{
s++;
if ((Details.color.r || Details.color.g || Details.color.b) && !japShit) {
wchar c = *s;
if (IsJapanese())
c &= 0x7FFF;
switch (c) {
case 'N':
case 'n':
NewLine = true;
break;
case 'b': SetColor(CRGBA(128, 167, 243, 255)); break;
case 'g': SetColor(CRGBA(95, 160, 106, 255)); break;
case 'h': SetColor(CRGBA(225, 225, 225, 255)); break;
case 'l': SetColor(CRGBA(0, 0, 0, 255)); break;
case 'p': SetColor(CRGBA(168, 110, 252, 255)); break;
case 'r': SetColor(CRGBA(113, 43, 73, 255)); break;
case 'w': SetColor(CRGBA(175, 175, 175, 255)); break;
case 'y': SetColor(CRGBA(210, 196, 106, 255)); break;
2020-11-05 15:05:16 +00:00
#ifdef BUTTON_ICONS
case 'U': PS2Symbol = BUTTON_UP; break;
case 'D': PS2Symbol = BUTTON_DOWN; break;
case '<': PS2Symbol = BUTTON_LEFT; break;
case '>': PS2Symbol = BUTTON_RIGHT; break;
case 'X': PS2Symbol = BUTTON_CROSS; break;
case 'O': PS2Symbol = BUTTON_CIRCLE; break;
case 'Q': PS2Symbol = BUTTON_SQUARE; break;
case 'T': PS2Symbol = BUTTON_TRIANGLE; break;
case 'K': PS2Symbol = BUTTON_L1; break;
case 'M': PS2Symbol = BUTTON_L2; break;
case 'A': PS2Symbol = BUTTON_L3; break;
case 'J': PS2Symbol = BUTTON_R1; break;
case 'V': PS2Symbol = BUTTON_R2; break;
case 'C': PS2Symbol = BUTTON_R3; break;
2021-02-10 06:57:51 +00:00
case 'H': PS2Symbol = BUTTON_RSTICK_UP; break;
case 'L': PS2Symbol = BUTTON_RSTICK_DOWN; break;
2021-01-02 10:50:28 +00:00
case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break;
case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break;
2020-11-05 15:05:16 +00:00
#endif
2020-04-26 20:49:24 +00:00
}
} else if (IsJapanese()) {
if ((*s & 0x7FFF) == 'N' || (*s & 0x7FFF) == 'n')
NewLine = true;
}
while ((!IsJapanese() || (*s != JAP_TERMINATION)) && *s != '~') s++;
return s + 1;
}
#else
wchar*
2020-06-07 02:12:01 +00:00
CFont::ParseToken(wchar *s)
2020-04-26 20:49:24 +00:00
{
2020-06-07 07:36:37 +00:00
Details.anonymous_23 = false;
2020-04-26 20:49:24 +00:00
s++;
if(Details.color.r || Details.color.g || Details.color.b)
switch(*s){
2020-06-07 02:12:01 +00:00
case 'B':
Details.bBold = !Details.bBold;
2020-10-10 11:23:17 +00:00
break;
2020-04-26 20:49:24 +00:00
case 'N':
case 'n':
2021-01-16 14:06:11 +00:00
NewLine = true;
2020-04-26 20:49:24 +00:00
break;
2021-01-12 23:01:04 +00:00
case 'b':
Details.color.r = 27;
Details.color.g = 89;
Details.color.b = 130;
Details.anonymous_23 = true;
break;
2020-06-07 02:12:01 +00:00
case 'f':
Details.bFlash = !Details.bFlash;
2020-10-10 11:23:17 +00:00
if (!Details.bFlash)
2020-06-07 02:12:01 +00:00
Details.color.a = 255;
break;
2021-01-12 23:01:04 +00:00
case 'g':
Details.color.r = 255;
Details.color.g = 150;
Details.color.b = 225;
Details.anonymous_23 = true;
break;
case 'h':
Details.color.r = 225;
Details.color.g = 225;
Details.color.b = 225;
Details.anonymous_23 = true;
break;
case 'l':
Details.color.r = 0;
Details.color.g = 0;
Details.color.b = 0;
Details.anonymous_23 = true;
break;
case 'o':
Details.color.r = 229;
Details.color.g = 125;
Details.color.b = 126;
Details.anonymous_23 = true;
break;
case 'p':
Details.color.r = 168;
Details.color.g = 110;
Details.color.b = 252;
Details.anonymous_23 = true;
break;
case 'q':
Details.color.r = 199;
Details.color.g = 144;
Details.color.b = 203;
Details.anonymous_23 = true;
break;
case 'r':
Details.color.r = 255;
Details.color.g = 150;
Details.color.b = 225;
Details.anonymous_23 = true;
break;
case 't':
Details.color.r = 86;
Details.color.g = 212;
Details.color.b = 146;
Details.anonymous_23 = true;
break;
case 'w':
Details.color.r = 175;
Details.color.g = 175;
Details.color.b = 175;
Details.anonymous_23 = true;
break;
case 'x':
2020-07-24 17:43:51 +00:00
#ifdef FIX_BUGS
2021-01-12 23:01:04 +00:00
Details.color.r = 0;
Details.color.g = 255;
Details.color.b = 255;
2020-07-24 17:43:51 +00:00
#else
2021-01-12 23:01:04 +00:00
Details.color.r = 132;
Details.color.g = 146;
Details.color.b = 197;
2020-07-24 17:43:51 +00:00
#endif
2021-01-12 23:01:04 +00:00
Details.anonymous_23 = true;
break;
case 'y':
Details.color.r = 255;
Details.color.g = 227;
Details.color.b = 79;
Details.anonymous_23 = true;
break;
2020-11-05 15:05:16 +00:00
#ifdef BUTTON_ICONS
case 'U': PS2Symbol = BUTTON_UP; break;
case 'D': PS2Symbol = BUTTON_DOWN; break;
case '<': PS2Symbol = BUTTON_LEFT; break;
case '>': PS2Symbol = BUTTON_RIGHT; break;
case 'X': PS2Symbol = BUTTON_CROSS; break;
case 'O': PS2Symbol = BUTTON_CIRCLE; break;
case 'Q': PS2Symbol = BUTTON_SQUARE; break;
case 'T': PS2Symbol = BUTTON_TRIANGLE; break;
case 'K': PS2Symbol = BUTTON_L1; break;
case 'M': PS2Symbol = BUTTON_L2; break;
case 'A': PS2Symbol = BUTTON_L3; break;
case 'J': PS2Symbol = BUTTON_R1; break;
case 'V': PS2Symbol = BUTTON_R2; break;
case 'C': PS2Symbol = BUTTON_R3; break;
2021-02-10 06:57:51 +00:00
case 'H': PS2Symbol = BUTTON_RSTICK_UP; break;
case 'L': PS2Symbol = BUTTON_RSTICK_DOWN; break;
2021-01-02 10:50:28 +00:00
case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break;
case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break;
2020-11-05 15:05:16 +00:00
#endif
2020-04-26 20:49:24 +00:00
}
while(*s != '~') s++;
2020-06-07 07:36:37 +00:00
if (*(++s) == '~')
2020-06-07 02:12:01 +00:00
s = ParseToken(s);
return s;
2020-04-26 20:49:24 +00:00
}
#endif
2021-01-16 14:06:11 +00:00
void
CFont::FilterOutTokensFromString(wchar *str)
2020-06-07 02:12:01 +00:00
{
2021-01-16 14:06:11 +00:00
int newIdx = 0;
wchar copy[256], *c;
UnicodeStrcpy(copy, str);
for (c = copy; *c != '\0'; c++) {
if (*c == '~') {
c++;
while (*c != '~') c++;
} else {
str[newIdx++] = *c;
2020-06-07 02:12:01 +00:00
}
}
2021-01-16 14:06:11 +00:00
str[newIdx] = '\0';
2020-06-07 02:12:01 +00:00
}
2020-04-26 20:49:24 +00:00
void
CFont::DrawFonts(void)
{
2020-06-07 01:11:10 +00:00
RenderFontBuffer();
}
void
2021-01-16 14:06:11 +00:00
CFont::SetScale(float x, float y)
2020-06-07 01:11:10 +00:00
{
2021-01-16 14:06:11 +00:00
#ifdef MORE_LANGUAGES
/*if (IsJapanese()) {
x *= 1.35f;
y *= 1.25f;
}*/
#endif
Details.scaleX = x;
Details.scaleY = y;
}
2020-06-07 07:36:37 +00:00
2021-01-16 14:06:11 +00:00
void
CFont::SetSlantRefPoint(float x, float y)
{
Details.slantRefX = x;
Details.slantRefY = y;
}
2020-06-07 01:11:10 +00:00
2021-01-16 14:06:11 +00:00
void
CFont::SetSlant(float s)
{
Details.slant = s;
}
2020-06-07 01:11:10 +00:00
2021-01-16 14:06:11 +00:00
void
CFont::SetColor(CRGBA col)
{
Details.color = col;
if (Details.alphaFade < 255.0f)
Details.color.a *= Details.alphaFade / 255.0f;
}
2020-06-07 07:36:37 +00:00
2021-01-16 14:06:11 +00:00
void
CFont::SetJustifyOn(void)
{
Details.justify = true;
Details.centre = false;
Details.rightJustify = false;
}
2020-06-07 07:36:37 +00:00
2021-01-16 14:06:11 +00:00
void
CFont::SetJustifyOff(void)
{
Details.justify = false;
Details.rightJustify = false;
2020-06-07 01:11:10 +00:00
}
2021-01-16 14:06:11 +00:00
void
CFont::SetCentreOn(void)
{
Details.centre = true;
Details.justify = false;
Details.rightJustify = false;
}
2020-06-07 01:11:10 +00:00
void
2021-01-16 14:06:11 +00:00
CFont::SetCentreOff(void)
2020-06-07 01:11:10 +00:00
{
2021-01-16 14:06:11 +00:00
Details.centre = false;
2020-06-07 01:11:10 +00:00
}
2021-01-16 14:06:11 +00:00
void
CFont::SetWrapx(float x)
2020-06-07 01:11:10 +00:00
{
2021-01-16 14:06:11 +00:00
Details.wrapX = x;
2020-04-26 20:49:24 +00:00
}
2021-01-16 14:06:11 +00:00
void
CFont::SetCentreSize(float s)
2020-04-26 20:49:24 +00:00
{
2021-01-16 14:06:11 +00:00
Details.centreSize = s;
2020-04-26 20:49:24 +00:00
}
2021-01-16 14:06:11 +00:00
void
CFont::SetBackgroundOn(void)
{
Details.background = true;
}
2020-04-26 20:49:24 +00:00
void
2021-01-16 14:06:11 +00:00
CFont::SetBackgroundOff(void)
2020-04-26 20:49:24 +00:00
{
2021-01-16 14:06:11 +00:00
Details.background = false;
2020-04-26 20:49:24 +00:00
}
void
CFont::SetBackgroundColor(CRGBA col)
{
Details.backgroundColor = col;
}
void
2021-01-16 14:06:11 +00:00
CFont::SetBackGroundOnlyTextOn(void)
2020-04-26 20:49:24 +00:00
{
2021-01-16 14:06:11 +00:00
Details.backgroundOnlyText = true;
}
void
CFont::SetBackGroundOnlyTextOff(void)
{
Details.backgroundOnlyText = false;
}
void
CFont::SetRightJustifyOn(void)
{
Details.rightJustify = true;
Details.justify = false;
Details.centre = false;
}
void
CFont::SetRightJustifyOff(void)
{
Details.rightJustify = false;
Details.justify = false;
Details.centre = false;
}
void
CFont::SetPropOff(void)
{
Details.proportional = false;
}
void
CFont::SetPropOn(void)
{
Details.proportional = true;
}
void
CFont::SetFontStyle(int16 style)
{
if (style == FONT_HEADING) {
Details.style = FONT_STANDARD;
Details.bFontHalfTexture = true;
} else {
Details.style = style;
Details.bFontHalfTexture = false;
}
}
void
CFont::SetRightJustifyWrap(float wrap)
{
Details.rightJustifyWrap = wrap;
}
void
CFont::SetAlphaFade(float fade)
{
Details.alphaFade = fade;
2020-04-26 20:49:24 +00:00
}
void
CFont::SetDropColor(CRGBA col)
{
Details.dropColor = col;
if (Details.alphaFade < 255.0f)
Details.dropColor.a *= Details.alphaFade / 255.0f;
}
void
2021-01-16 14:06:11 +00:00
CFont::SetDropShadowPosition(int16 pos)
{
2021-01-16 14:06:11 +00:00
Details.dropShadowPosition = pos;
}
2021-01-16 14:06:11 +00:00
wchar CFont::FindNewCharacter(wchar c)
{
if (c >= 16 && c <= 26) return c + 128;
if (c >= 8 && c <= 9) return c + 86;
if (c == 4) return c + 89;
if (c == 7) return 206;
if (c == 14) return 207;
if (c >= 33 && c <= 58) return c + 122;
if (c >= 65 && c <= 90) return c + 90;
if (c >= 96 && c <= 118) return c + 85;
if (c >= 119 && c <= 140) return c + 62;
if (c >= 141 && c <= 142) return 204;
if (c == 143) return 205;
if (c == 1) return 208;
return c;
}
2021-01-16 14:06:11 +00:00
wchar
CFont::character_code(uint8 c)
{
if(c < 128)
return c;
return foreign_table[c-128];
}