mirror of https://github.com/OpenRCT2/OpenRCT2.git
implement utf8, part 5
This commit is contained in:
parent
1682eae048
commit
795c01cab5
|
@ -138,6 +138,7 @@ config_enum_definition _languageEnum[] = {
|
|||
{ "sv-SE", LANGUAGE_SWEDISH },
|
||||
{ "it-IT", LANGUAGE_ITALIAN },
|
||||
{ "pt-BR", LANGUAGE_PORTUGUESE_BR },
|
||||
{ "zh-Hant", LANGUAGE_CHINESE_TRADITIONAL },
|
||||
END_OF_ENUM
|
||||
};
|
||||
|
||||
|
|
|
@ -933,7 +933,7 @@ bool ttf_initialise()
|
|||
}
|
||||
}
|
||||
|
||||
_ttfFontOffsetX = 0;
|
||||
_ttfFontOffsetX = 1;
|
||||
_ttfFontOffsetY = -3;
|
||||
_ttfInitialised = true;
|
||||
}
|
||||
|
@ -972,22 +972,27 @@ typedef struct {
|
|||
uint16 font_sprite_base;
|
||||
} text_draw_info;
|
||||
|
||||
static void ttf_draw_character_sprite(rct_drawpixelinfo *dpi, int codepoint, text_draw_info *info)
|
||||
{
|
||||
uint32 charOffset = info->font_sprite_base + utf8_get_sprite_offset_for_codepoint(codepoint);
|
||||
int charWidth = _spriteFontCharacterWidths[charOffset] & 0xFF;
|
||||
|
||||
if (!(info->flags & TEXT_DRAW_FLAG_NO_DRAW)) {
|
||||
RCT2_GLOBAL(0x009ABDA4, uint8*) = (uint8*)&info->palette;
|
||||
RCT2_GLOBAL(0x00EDF81C, uint32) = (IMAGE_TYPE_USE_PALETTE << 28);
|
||||
gfx_draw_sprite_palette_set(dpi, SPR_CHAR_START + ((IMAGE_TYPE_USE_PALETTE << 28) | charOffset), info->x, info->y, info->palette, NULL);
|
||||
}
|
||||
|
||||
info->x += charWidth;
|
||||
}
|
||||
|
||||
static void ttf_draw_string_raw_sprite(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info)
|
||||
{
|
||||
const utf8 *ch = text;
|
||||
int codepoint;
|
||||
|
||||
while (!utf8_is_format_code(codepoint = utf8_get_next(ch, &ch))) {
|
||||
uint32 charOffset = info->font_sprite_base + utf8_get_sprite_offset_for_codepoint(codepoint);
|
||||
int charWidth = _spriteFontCharacterWidths[charOffset] & 0xFF;
|
||||
|
||||
if (!(info->flags & TEXT_DRAW_FLAG_NO_DRAW)) {
|
||||
RCT2_GLOBAL(0x009ABDA4, uint8*) = (uint8*)&info->palette;
|
||||
RCT2_GLOBAL(0x00EDF81C, uint32) = (IMAGE_TYPE_USE_PALETTE << 28);
|
||||
gfx_draw_sprite_palette_set(dpi, SPR_CHAR_START + ((IMAGE_TYPE_USE_PALETTE << 28) | charOffset), info->x, info->y, info->palette, NULL);
|
||||
}
|
||||
|
||||
info->x += charWidth;
|
||||
ttf_draw_character_sprite(dpi, codepoint, info);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1206,7 +1211,11 @@ static const utf8 *ttf_process_glyph_run(rct_drawpixelinfo *dpi, const utf8 *tex
|
|||
const utf8 *lastCh;
|
||||
int codepoint;
|
||||
|
||||
bool isTTF = info->flags & TEXT_DRAW_FLAG_TTF;
|
||||
while (!utf8_is_format_code(codepoint = utf8_get_next(ch, &lastCh))) {
|
||||
if (isTTF && utf8_should_use_sprite_for_codepoint(codepoint)) {
|
||||
break;
|
||||
}
|
||||
ch = lastCh;
|
||||
}
|
||||
if (codepoint == 0) {
|
||||
|
@ -1233,9 +1242,8 @@ static void ttf_process_string(rct_drawpixelinfo *dpi, const utf8 *text, text_dr
|
|||
if (utf8_is_format_code(codepoint)) {
|
||||
ch = ttf_process_format_code(dpi, ch, info);
|
||||
} else if (isTTF && utf8_should_use_sprite_for_codepoint(codepoint)) {
|
||||
info->flags &= ~TEXT_DRAW_FLAG_TTF;
|
||||
ch = ttf_process_glyph_run(dpi, ch, info);
|
||||
info->flags |= TEXT_DRAW_FLAG_TTF;
|
||||
ttf_draw_character_sprite(dpi, codepoint, info);
|
||||
ch = nextCh;
|
||||
} else {
|
||||
ch = ttf_process_glyph_run(dpi, ch, info);
|
||||
}
|
||||
|
@ -1246,9 +1254,9 @@ static void ttf_process_initial_colour(int colour, text_draw_info *info)
|
|||
{
|
||||
if (colour != 254 && colour != 255) {
|
||||
info->flags &= ~(1 | 2 | 4 | 8);
|
||||
if (info->font_sprite_base < 0) {
|
||||
if ((sint16)info->font_sprite_base < 0) {
|
||||
info->flags |= 4;
|
||||
if (info->font_sprite_base != -1) {
|
||||
if ((sint16)info->font_sprite_base != -1) {
|
||||
info->flags |= 8;
|
||||
}
|
||||
info->font_sprite_base = 224;
|
||||
|
|
|
@ -725,8 +725,6 @@ static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widg
|
|||
gfx_draw_string_centred_clipped(dpi, widget->image, (void*)0x013CE952, colour, l, t, widget->right - widget->left - 2);
|
||||
}
|
||||
|
||||
static const utf8 CheckBoxMarkString[] = { 0xE2, 0x9C, 0x93, 0x00 };
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006EBAD9
|
||||
|
@ -850,11 +848,6 @@ static void widget_scroll_draw(rct_drawpixelinfo *dpi, rct_window *w, int widget
|
|||
window_event_scroll_paint_call(w, &scroll_dpi, scrollIndex);
|
||||
}
|
||||
|
||||
static const utf8 BlackUpArrowString[] = { 0xC2, 0x8E, 0xE2, 0x96, 0xB2, 0x00 };
|
||||
static const utf8 BlackDownArrowString[] = { 0xC2, 0x8E, 0xE2, 0x96, 0xBC, 0x00 };
|
||||
static const utf8 BlackLeftArrowString[] = { 0xC2, 0x8E, 0xE2, 0x96, 0x80, 0x00 };
|
||||
static const utf8 BlackRightArrowString[] = { 0xC2, 0x8E, 0xE2, 0x96, 0xB6, 0x00 };
|
||||
|
||||
static void widget_hscrollbar_draw(rct_drawpixelinfo *dpi, rct_scroll *scroll, int l, int t, int r, int b, int colour)
|
||||
{
|
||||
colour &= 0x7F;
|
||||
|
|
|
@ -33,20 +33,38 @@ typedef struct {
|
|||
char *string_data;
|
||||
} language_data;
|
||||
|
||||
enum {
|
||||
RCT2_LANGUAGE_ID_ENGLISH_UK,
|
||||
RCT2_LANGUAGE_ID_ENGLISH_US,
|
||||
RCT2_LANGUAGE_ID_FRENCH,
|
||||
RCT2_LANGUAGE_ID_GERMAN,
|
||||
RCT2_LANGUAGE_ID_SPANISH,
|
||||
RCT2_LANGUAGE_ID_ITALIAN,
|
||||
RCT2_LANGUAGE_ID_DUTCH,
|
||||
RCT2_LANGUAGE_ID_SWEDISH,
|
||||
RCT2_LANGUAGE_ID_8,
|
||||
RCT2_LANGUAGE_ID_KOREAN,
|
||||
RCT2_LANGUAGE_ID_CHINESE_TRADITIONAL,
|
||||
RCT2_LANGUAGE_ID_CHINESE_SIMPLIFIED,
|
||||
RCT2_LANGUAGE_ID_12,
|
||||
RCT2_LANGUAGE_ID_PORTUGESE,
|
||||
RCT2_LANGUAGE_ID_END = 255
|
||||
};
|
||||
|
||||
const language_descriptor LanguagesDescriptors[LANGUAGE_COUNT] = {
|
||||
{ "", "", "", "", FONT_OPENRCT2_SPRITE }, // LANGUAGE_UNDEFINED
|
||||
{ "en-GB", "English (UK)", "English (UK)", "english_uk", FONT_OPENRCT2_SPRITE }, // LANGUAGE_ENGLISH_UK
|
||||
{ "en-US", "English (US)", "English (US)", "english_us", FONT_OPENRCT2_SPRITE }, // LANGUAGE_ENGLISH_US
|
||||
{ "de-DE", "German", "Deutsch", "german", FONT_OPENRCT2_SPRITE }, // LANGUAGE_GERMAN
|
||||
{ "nl-NL", "Dutch", "Nederlands", "dutch", FONT_OPENRCT2_SPRITE }, // LANGUAGE_DUTCH
|
||||
{ "fr-FR", "French", "Fran\xC3\xA7" "ais", "french", FONT_OPENRCT2_SPRITE }, // LANGUAGE_FRENCH
|
||||
{ "hu-HU", "Hungarian", "Magyar", "hungarian", FONT_OPENRCT2_SPRITE }, // LANGUAGE_HUNGARIAN
|
||||
{ "pl-PL", "Polish", "Polski", "polish", FONT_OPENRCT2_SPRITE }, // LANGUAGE_POLISH
|
||||
{ "es-ES", "Spanish", "Espa\xC3\xB1ol", "spanish_sp", FONT_OPENRCT2_SPRITE }, // LANGUAGE_SPANISH
|
||||
{ "sv-SE", "Swedish", "Svenska", "swedish", FONT_OPENRCT2_SPRITE }, // LANGUAGE_SWEDISH
|
||||
{ "it-IT", "Italian", "Italiano", "italian", FONT_OPENRCT2_SPRITE }, // LANGUAGE_ITALIAN
|
||||
{ "pt-BR", "Portuguese (BR)", "Portug\xC3\xAAs (BR)", "portuguese_br", FONT_OPENRCT2_SPRITE }, // LANGUAGE_PORTUGUESE_BR
|
||||
{ "zh-Hant", "Chinese (Traditional)", "Chinese (Traditional)", "chinese_traditional", "msjh.ttc" }, // LANGUAGE_CHINESE_TRADITIONAL
|
||||
{ "", "", "", "", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_ENGLISH_UK }, // LANGUAGE_UNDEFINED
|
||||
{ "en-GB", "English (UK)", "English (UK)", "english_uk", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_ENGLISH_UK }, // LANGUAGE_ENGLISH_UK
|
||||
{ "en-US", "English (US)", "English (US)", "english_us", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_ENGLISH_US }, // LANGUAGE_ENGLISH_US
|
||||
{ "de-DE", "German", "Deutsch", "german", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_GERMAN }, // LANGUAGE_GERMAN
|
||||
{ "nl-NL", "Dutch", "Nederlands", "dutch", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_DUTCH }, // LANGUAGE_DUTCH
|
||||
{ "fr-FR", "French", "Fran\xC3\xA7" "ais", "french", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_FRENCH }, // LANGUAGE_FRENCH
|
||||
{ "hu-HU", "Hungarian", "Magyar", "hungarian", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_ENGLISH_UK }, // LANGUAGE_HUNGARIAN
|
||||
{ "pl-PL", "Polish", "Polski", "polish", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_ENGLISH_UK }, // LANGUAGE_POLISH
|
||||
{ "es-ES", "Spanish", "Espa\xC3\xB1ol", "spanish_sp", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_SPANISH }, // LANGUAGE_SPANISH
|
||||
{ "sv-SE", "Swedish", "Svenska", "swedish", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_SWEDISH }, // LANGUAGE_SWEDISH
|
||||
{ "it-IT", "Italian", "Italiano", "italian", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_ITALIAN }, // LANGUAGE_ITALIAN
|
||||
{ "pt-BR", "Portuguese (BR)", "Portug\xC3\xAAs (BR)", "portuguese_br", FONT_OPENRCT2_SPRITE, RCT2_LANGUAGE_ID_PORTUGESE }, // LANGUAGE_PORTUGUESE_BR
|
||||
{ "zh-Hant", "Chinese (Traditional)", "Chinese (Traditional)", "chinese_traditional", "msjh.ttc", RCT2_LANGUAGE_ID_CHINESE_TRADITIONAL }, // LANGUAGE_CHINESE_TRADITIONAL
|
||||
};
|
||||
|
||||
int gCurrentLanguage = LANGUAGE_UNDEFINED;
|
||||
|
@ -58,6 +76,12 @@ language_data _languageCurrent = { 0 };
|
|||
|
||||
const char **_languageOriginal = (char**)0x009BF2D4;
|
||||
|
||||
const utf8 BlackUpArrowString[] = { 0xC2, 0x8E, 0xE2, 0x96, 0xB2, 0x00 };
|
||||
const utf8 BlackDownArrowString[] = { 0xC2, 0x8E, 0xE2, 0x96, 0xBC, 0x00 };
|
||||
const utf8 BlackLeftArrowString[] = { 0xC2, 0x8E, 0xE2, 0x97, 0x80, 0x00 };
|
||||
const utf8 BlackRightArrowString[] = { 0xC2, 0x8E, 0xE2, 0x96, 0xB6, 0x00 };
|
||||
const utf8 CheckBoxMarkString[] = { 0xE2, 0x9C, 0x93, 0x00 };
|
||||
|
||||
static int language_open_file(const char *filename, language_data *language);
|
||||
static void language_close(language_data *language);
|
||||
|
||||
|
@ -299,56 +323,141 @@ static void language_close(language_data *language)
|
|||
}
|
||||
|
||||
const int OpenRCT2LangIdToObjectLangId[] = {
|
||||
0, 0, 1, 3, 6, 2, 0, 0, 4, 7, 5, 13
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
3,
|
||||
6,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
4,
|
||||
7,
|
||||
5,
|
||||
13
|
||||
};
|
||||
|
||||
#define STEX_BASE_STRING_ID 3447
|
||||
#define NONSTEX_BASE_STRING_ID 3463
|
||||
#define MAX_OBJECT_CACHED_STRINGS 2048
|
||||
|
||||
/* rct2: 0x0098DA16 */
|
||||
uint16 ObjectTypeStringTableCount[] = { 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 };
|
||||
|
||||
utf8 *_cachedObjectStrings[MAX_OBJECT_CACHED_STRINGS] = { NULL };
|
||||
|
||||
void utf8_trim_string(utf8 *text)
|
||||
{
|
||||
utf8 *src = text;
|
||||
utf8 *dst = text;
|
||||
utf8 *last = text;
|
||||
int codepoint;
|
||||
|
||||
// Trim left
|
||||
while ((codepoint = utf8_get_next(src, &src)) != 0) {
|
||||
if (codepoint != ' ') {
|
||||
dst = utf8_write_codepoint(dst, codepoint);
|
||||
last = dst;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (codepoint != 0) {
|
||||
// Trim right
|
||||
while ((codepoint = utf8_get_next(src, &src)) != 0) {
|
||||
dst = utf8_write_codepoint(dst, codepoint);
|
||||
if (codepoint != ' ') {
|
||||
last = dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
*last = 0;
|
||||
}
|
||||
|
||||
static utf8 *convert_multibyte_charset(const char *src)
|
||||
{
|
||||
int reservedLength = (strlen(src) * 4) + 1;
|
||||
utf8 *buffer = malloc(reservedLength);
|
||||
utf8 *dst = buffer;
|
||||
for (const uint8 *ch = src; *ch != 0;) {
|
||||
if (*ch == 0xFF) {
|
||||
ch++;
|
||||
uint8 a = *ch++;
|
||||
uint8 b = *ch++;
|
||||
uint16 codepoint = (a << 8) | b;
|
||||
dst = utf8_write_codepoint(dst, codepoint);
|
||||
} else {
|
||||
*dst++ = *ch++;
|
||||
}
|
||||
}
|
||||
*dst++ = 0;
|
||||
int actualLength = dst - buffer;
|
||||
return realloc(buffer, actualLength);
|
||||
}
|
||||
|
||||
static bool rct2_language_is_multibyte_charset(int languageId)
|
||||
{
|
||||
switch (languageId) {
|
||||
case RCT2_LANGUAGE_ID_KOREAN:
|
||||
case RCT2_LANGUAGE_ID_CHINESE_TRADITIONAL:
|
||||
case RCT2_LANGUAGE_ID_CHINESE_SIMPLIFIED:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* rct2: 0x006A9E24*/
|
||||
rct_string_id object_get_localised_text(uint8_t** pStringTable/*ebp*/, int type/*ecx*/, int index/*ebx*/, int tableindex/*edx*/)
|
||||
{
|
||||
char* pString = NULL;
|
||||
uint8 languageId, chosenLanguageId;
|
||||
char *pString = NULL;
|
||||
int result = 0;
|
||||
while (true)
|
||||
{
|
||||
uint8_t language_code = *(*pStringTable)++;
|
||||
|
||||
if (language_code == 0xFF) //end of string table
|
||||
break;
|
||||
bool isBlank;
|
||||
|
||||
while ((languageId = *(*pStringTable)++) != RCT2_LANGUAGE_ID_END) {
|
||||
isBlank = true;
|
||||
|
||||
// Strings that are just ' ' are set as invalid langauges.
|
||||
// But if there is no real string then it will set the string as
|
||||
// the blank string
|
||||
for (char *ch = *pStringTable; *ch != 0; ch++) {
|
||||
if (!isblank(*ch)) {
|
||||
isBlank = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isBlank) languageId = 0xFE;
|
||||
|
||||
// This is the ideal situation. Language found
|
||||
if (language_code == OpenRCT2LangIdToObjectLangId[gCurrentLanguage])//1)
|
||||
{
|
||||
if (languageId == LanguagesDescriptors[gCurrentLanguage].rct2_original_id) {
|
||||
chosenLanguageId = languageId;
|
||||
pString = *pStringTable;
|
||||
result |= 1;
|
||||
}
|
||||
|
||||
// Just in case always load english into pString
|
||||
if (language_code == 0 && !(result & 1))
|
||||
{
|
||||
if (languageId == RCT2_LANGUAGE_ID_ENGLISH_UK && !(result & 1)) {
|
||||
chosenLanguageId = languageId;
|
||||
pString = *pStringTable;
|
||||
result |= 2;
|
||||
}
|
||||
|
||||
// Failing that fall back to whatever is first string
|
||||
if (!(result & 7))
|
||||
{
|
||||
if (!(result & 7)) {
|
||||
chosenLanguageId = languageId;
|
||||
pString = *pStringTable;
|
||||
result |= 4;
|
||||
if (!isBlank) result |= 4;
|
||||
}
|
||||
|
||||
// Skip over the actual string entry to get to the next
|
||||
// entry
|
||||
// Skip over the actual string entry to get to the next entry
|
||||
while (*(*pStringTable)++ != 0);
|
||||
}
|
||||
|
||||
// If not scenario text
|
||||
if (RCT2_GLOBAL(0x9ADAFC, uint8_t) == 0)
|
||||
{
|
||||
int stringid = 3463;
|
||||
for (int i = 0; i < type; i++)
|
||||
{
|
||||
if (RCT2_GLOBAL(0x009ADAFC, uint8) == 0) {
|
||||
int stringid = NONSTEX_BASE_STRING_ID;
|
||||
for (int i = 0; i < type; i++) {
|
||||
int nrobjects = object_entry_group_counts[i];
|
||||
int nrstringtables = ObjectTypeStringTableCount[i];
|
||||
stringid += nrobjects * nrstringtables;
|
||||
|
@ -358,23 +467,48 @@ rct_string_id object_get_localised_text(uint8_t** pStringTable/*ebp*/, int type/
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_CURR_OBJECT_BASE_STRING_ID, uint32) = stringid;
|
||||
stringid += tableindex;
|
||||
|
||||
// cache UTF-8 string
|
||||
int cacheStringOffset = stringid - STEX_BASE_STRING_ID;
|
||||
utf8 **cacheString = &_cachedObjectStrings[cacheStringOffset];
|
||||
if (*cacheString != NULL) {
|
||||
free(*cacheString);
|
||||
}
|
||||
if (rct2_language_is_multibyte_charset(chosenLanguageId)) {
|
||||
*cacheString = convert_multibyte_charset(pString);
|
||||
} else {
|
||||
*cacheString = win1252_to_utf8_alloc(pString);
|
||||
}
|
||||
utf8_trim_string(*cacheString);
|
||||
|
||||
//put pointer in stringtable
|
||||
if (_languageCurrent.num_strings > stringid)
|
||||
_languageCurrent.strings[stringid] = pString;
|
||||
_languageCurrent.strings[stringid] = *cacheString;
|
||||
// Until all string related functions are finished copy
|
||||
// to old array as well.
|
||||
_languageOriginal[stringid] = pString;
|
||||
_languageOriginal[stringid] = *cacheString;
|
||||
return stringid;
|
||||
}
|
||||
else
|
||||
{
|
||||
int stringid = 3447 + tableindex;
|
||||
} else {
|
||||
int stringid = STEX_BASE_STRING_ID + tableindex;
|
||||
|
||||
// cache UTF-8 string
|
||||
int cacheStringOffset = stringid - STEX_BASE_STRING_ID;
|
||||
utf8 **cacheString = &_cachedObjectStrings[cacheStringOffset];
|
||||
if (*cacheString != NULL) {
|
||||
free(*cacheString);
|
||||
}
|
||||
if (rct2_language_is_multibyte_charset(chosenLanguageId)) {
|
||||
*cacheString = convert_multibyte_charset(pString);
|
||||
} else {
|
||||
*cacheString = win1252_to_utf8_alloc(pString);
|
||||
}
|
||||
utf8_trim_string(*cacheString);
|
||||
|
||||
//put pointer in stringtable
|
||||
if (_languageCurrent.num_strings > stringid)
|
||||
_languageCurrent.strings[stringid] = pString;
|
||||
_languageCurrent.strings[stringid] = *cacheString;
|
||||
// Until all string related functions are finished copy
|
||||
// to old array as well.
|
||||
_languageOriginal[stringid] = pString;
|
||||
_languageOriginal[stringid] = *cacheString;
|
||||
return stringid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ typedef struct {
|
|||
const utf8 *native_name;
|
||||
const utf8 *path;
|
||||
const utf8 *font;
|
||||
uint8 rct2_original_id;
|
||||
} language_descriptor;
|
||||
|
||||
extern const language_descriptor LanguagesDescriptors[LANGUAGE_COUNT];
|
||||
|
@ -56,6 +57,12 @@ extern int gCurrentLanguage;
|
|||
extern bool gUseTrueTypeFont;
|
||||
extern const utf8 *gTrueTypeFontPath;
|
||||
|
||||
extern const utf8 BlackUpArrowString[];
|
||||
extern const utf8 BlackDownArrowString[];
|
||||
extern const utf8 BlackLeftArrowString[];
|
||||
extern const utf8 BlackRightArrowString[];
|
||||
extern const utf8 CheckBoxMarkString[];
|
||||
|
||||
const char *language_get_string(rct_string_id id);
|
||||
int language_open(int id);
|
||||
void language_close_all();
|
||||
|
|
|
@ -833,6 +833,14 @@ int get_string_length(const utf8* text)
|
|||
return ch - text - 1;
|
||||
}
|
||||
|
||||
utf8 *win1252_to_utf8_alloc(const char *src)
|
||||
{
|
||||
int reservedSpace = (strlen(src) * 4) + 1;
|
||||
utf8 *result = malloc(reservedSpace);
|
||||
int actualSpace = win1252_to_utf8(result, src, reservedSpace);
|
||||
return (utf8*)realloc(result, actualSpace);
|
||||
}
|
||||
|
||||
int win1252_to_utf8(utf8string dst, const char *src, int maxBufferLength)
|
||||
{
|
||||
utf16 stackBuffer[256];
|
||||
|
|
|
@ -42,6 +42,7 @@ rct_string_id user_string_allocate(int base, const char *text);
|
|||
void user_string_free(rct_string_id id);
|
||||
bool is_user_string_id(rct_string_id stringId);
|
||||
|
||||
utf8 *win1252_to_utf8_alloc(const char *src);
|
||||
int win1252_to_utf8(utf8string dst, const char *src, int maxBufferLength);
|
||||
|
||||
#define MAX_USER_STRINGS 1024
|
||||
|
|
|
@ -1439,14 +1439,13 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi
|
|||
if (*listItem->flags & (OBJECT_SELECTION_FLAG_IN_USE | OBJECT_SELECTION_FLAG_REQUIRED | OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED))
|
||||
colour2 |= 0x40;
|
||||
|
||||
gfx_draw_string(dpi, (char*)0x009DED72, colour2, x, y);
|
||||
gfx_draw_string(dpi, (char*)CheckBoxMarkString, colour2, x, y);
|
||||
}
|
||||
|
||||
x = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 15;
|
||||
|
||||
char *bufferWithColour = (char*)0x0141ED68;
|
||||
char *buffer = bufferWithColour + 1;
|
||||
bufferWithColour[0] = colour;
|
||||
char *buffer = utf8_write_codepoint(bufferWithColour, colour);
|
||||
if (*listItem->flags & OBJECT_SELECTION_FLAG_6) {
|
||||
colour = w->colours[1] & 0x7F;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = -1;
|
||||
|
|
|
@ -1200,7 +1200,7 @@ static void window_editor_objective_options_rides_scrollpaint(rct_window *w, rct
|
|||
ride = GET_RIDE(i);
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = stringId == 1193 ? 0xFFFE : 0xFFFF;
|
||||
gfx_draw_string(dpi, (char*)0x009DED72, w->colours[1] & 0x7F, 2, y);
|
||||
gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1] & 0x7F, 2, y);
|
||||
}
|
||||
|
||||
// Ride name
|
||||
|
|
|
@ -881,7 +881,7 @@ void window_themes_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scroll
|
|||
gfx_fill_rect_inset(dpi, _button_offset_x + 12 * j, y + _check_offset_y, _button_offset_x + 12 * j + 9, y + _check_offset_y + 10, w->colours[1], 0xE0);
|
||||
if (get_colour_scheme_tab_by_index(i)->colours[j] & 0x80) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = -1;
|
||||
gfx_draw_string(dpi, (char*)0x009DED72, w->colours[1] & 0x7F, _button_offset_x + 12 * j, y + _check_offset_y);
|
||||
gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1] & 0x7F, _button_offset_x + 12 * j, y + _check_offset_y);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue