mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-12 10:32:26 +01:00
Merge pull request #2378 from IntelOrca/support-unicode-currencies
support unicode currencies with ascii fallback
This commit is contained in:
@@ -3899,7 +3899,7 @@ STR_5557 :Stay connected after desynchronisation (Multiplayer)
|
||||
STR_5558 :A restart is required for this setting to take effect
|
||||
STR_5559 :10 min. inspections
|
||||
STR_5560 :{SMALLFONT}{BLACK}Sets the inspection time to 'Every 10 minutes' on all rides
|
||||
STR_5561 :Failed to load language file
|
||||
STR_5561 :Failed to load language
|
||||
STR_5562 :WARNING!
|
||||
STR_5563 :This feature is currently unstable, take extra caution.
|
||||
STR_5564 :Insert Corrupt Element
|
||||
@@ -3918,6 +3918,7 @@ STR_5576 :Port:
|
||||
STR_5577 :South Korean Won (W)
|
||||
STR_5578 :Russian Rouble (R)
|
||||
STR_5579 :Window scale factor:
|
||||
STR_5580 :Czech koruna (Kc)
|
||||
|
||||
#####################
|
||||
# Rides/attractions #
|
||||
|
||||
@@ -126,3 +126,61 @@ int font_get_line_height_small(int fontSpriteBase)
|
||||
{
|
||||
return font_get_line_height(fontSpriteBase) / 2;
|
||||
}
|
||||
|
||||
bool font_supports_string(const utf8 *text, int fontSize)
|
||||
{
|
||||
const utf8 *src = text;
|
||||
|
||||
uint32 codepoint;
|
||||
while ((codepoint = utf8_get_next(src, &src)) != 0) {
|
||||
if (gUseTrueTypeFont) {
|
||||
bool supported = TTF_GlyphIsProvided(gCurrentTTFFontSet->size[fontSize].font, (uint16)codepoint);
|
||||
if (!supported) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
bool supported = false;
|
||||
switch (codepoint) {
|
||||
case FORMAT_ENDQUOTES:
|
||||
case FORMAT_AMINUSCULE:
|
||||
case FORMAT_UP:
|
||||
case FORMAT_SYMBOL_i:
|
||||
case FORMAT_CENT:
|
||||
case FORMAT_POUND:
|
||||
case FORMAT_YEN:
|
||||
case FORMAT_COPYRIGHT:
|
||||
case FORMAT_DOWN:
|
||||
case FORMAT_LEFTGUILLEMET:
|
||||
case FORMAT_TICK:
|
||||
case FORMAT_CROSS:
|
||||
case FORMAT_RIGHT:
|
||||
case FORMAT_DEGREE:
|
||||
case FORMAT_SYMBOL_RAILWAY:
|
||||
case FORMAT_SQUARED:
|
||||
case FORMAT_OPENQUOTES:
|
||||
case FORMAT_EURO:
|
||||
case FORMAT_SYMBOL_ROAD:
|
||||
case FORMAT_SYMBOL_FLAG:
|
||||
case FORMAT_APPROX:
|
||||
case FORMAT_POWERNEGATIVEONE:
|
||||
case FORMAT_BULLET:
|
||||
case FORMAT_RIGHTGUILLEMET:
|
||||
case FORMAT_SMALLUP:
|
||||
case FORMAT_SMALLDOWN:
|
||||
case FORMAT_LEFT:
|
||||
case FORMAT_INVERTEDQUESTION:
|
||||
supported = true;
|
||||
break;
|
||||
default:
|
||||
if (codepoint >= 32 && codepoint < 256) {
|
||||
supported = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!supported) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -43,5 +43,6 @@ int font_sprite_get_codepoint_sprite(int fontSpriteBase, int codepoint);
|
||||
int font_get_size_from_sprite_base(uint16 spriteBase);
|
||||
int font_get_line_height(int fontSpriteBase);
|
||||
int font_get_line_height_small(int fontSpriteBase);
|
||||
bool font_supports_string(const utf8 *text, int fontSize);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -881,8 +881,9 @@ static uint32 _ttf_getwidth_cache_get_or_add(TTF_Font *font, const utf8 *text)
|
||||
bool ttf_initialise()
|
||||
{
|
||||
if (!_ttfInitialised) {
|
||||
if (TTF_Init() != 0)
|
||||
if (TTF_Init() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]);
|
||||
@@ -893,6 +894,7 @@ bool ttf_initialise()
|
||||
fontDesc->font = TTF_OpenFont(fontPath, fontDesc->ptSize);
|
||||
if (fontDesc->font == NULL) {
|
||||
log_error("Unable to load '%s'", fontPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,17 +21,18 @@
|
||||
#include "currency.h"
|
||||
#include "string_ids.h"
|
||||
|
||||
const rct_currency_spec g_currency_specs[CURRENCY_END] = {
|
||||
{ 10 , "\xC2\xA3" , CURRENCY_PREFIX, STR_POUNDS }, // British Pound
|
||||
{ 10 , "$" , CURRENCY_PREFIX, STR_DOLLARS}, // US Dollar
|
||||
{ 10 , "F" , CURRENCY_SUFFIX, STR_FRANC }, // French Franc
|
||||
{ 10 , "DM" , CURRENCY_PREFIX, STR_DEUTSCHMARK }, // Deutschmark
|
||||
{ 1000 , "\xC2\xA5" , CURRENCY_PREFIX, STR_YEN }, // Japanese Yen
|
||||
{ 10 , "Pts" , CURRENCY_SUFFIX, STR_PESETA }, // Spanish Peseta
|
||||
{ 1000 , "L" , CURRENCY_PREFIX, STR_LIRA }, // Italian Lira
|
||||
{ 10 , "fl. " , CURRENCY_PREFIX, STR_GUILDERS }, // Dutch Guilder
|
||||
{ 10 , "kr." , CURRENCY_SUFFIX, STR_KRONA }, // Swedish Krona
|
||||
{ 10 , "\xE2\x82\xAC" , CURRENCY_PREFIX, STR_EUROS }, // Euro
|
||||
{ 10000 , "W" , CURRENCY_PREFIX, STR_WON }, // South Korean Won
|
||||
{ 1000 , "R " , CURRENCY_PREFIX, STR_ROUBLE }, // Russian Rouble
|
||||
const currency_descriptor CurrencyDescriptors[CURRENCY_END] = {
|
||||
{ 10 , CURRENCY_PREFIX, "\xC2\xA3" , CURRENCY_SUFFIX, "GBP" , STR_POUNDS }, // British Pound
|
||||
{ 10 , CURRENCY_PREFIX, "$" , CURRENCY_PREFIX, "$" , STR_DOLLARS }, // US Dollar
|
||||
{ 10 , CURRENCY_SUFFIX, "F" , CURRENCY_SUFFIX, "F" , STR_FRANC }, // French Franc
|
||||
{ 10 , CURRENCY_PREFIX, "DM" , CURRENCY_PREFIX, "DM" , STR_DEUTSCHMARK }, // Deutschmark
|
||||
{ 1000 , CURRENCY_PREFIX, "\xC2\xA5" , CURRENCY_SUFFIX, "YEN" , STR_YEN }, // Japanese Yen
|
||||
{ 10 , CURRENCY_SUFFIX, "Pts" , CURRENCY_SUFFIX, "Pts" , STR_PESETA }, // Spanish Peseta
|
||||
{ 1000 , CURRENCY_PREFIX, "L" , CURRENCY_PREFIX, "L" , STR_LIRA }, // Italian Lira
|
||||
{ 10 , CURRENCY_PREFIX, "\xC6\x92" , CURRENCY_PREFIX, "fl." , STR_GUILDERS }, // Dutch Guilder
|
||||
{ 10 , CURRENCY_SUFFIX, "kr." , CURRENCY_SUFFIX, "kr." , STR_KRONA }, // Swedish Krona
|
||||
{ 10 , CURRENCY_PREFIX, "\xE2\x82\xAC" , CURRENCY_SUFFIX, "EUR" , STR_EUROS }, // Euro
|
||||
{ 10000 , CURRENCY_PREFIX, "\xE2\x82\xA9" , CURRENCY_PREFIX, "W" , STR_WON }, // South Korean Won
|
||||
{ 1000 , CURRENCY_PREFIX, "R " , CURRENCY_PREFIX, "R " , STR_ROUBLE }, // Russian Rouble
|
||||
{ 100 , CURRENCY_SUFFIX, " K\xC4\x8D" , CURRENCY_SUFFIX, " Kc" , STR_CZECH_KORUNA }, // Czech koruna
|
||||
};
|
||||
|
||||
@@ -37,6 +37,7 @@ typedef enum {
|
||||
CURRENCY_EUROS, // Euro
|
||||
CURRENCY_WON, // South Korean Won
|
||||
CURRENCY_ROUBLE, // Russian Rouble
|
||||
CURRENCY_CZECH_KORUNA, // Czech koruna
|
||||
|
||||
CURRENCY_END // Last item
|
||||
} CURRENCY_TYPE;
|
||||
@@ -50,14 +51,16 @@ typedef enum {
|
||||
|
||||
// Currency format specification - inspired by OpenTTD
|
||||
typedef struct {
|
||||
// Rate is relative to 0.1 GBP
|
||||
// Rate is relative to 0.10 GBP
|
||||
int rate;
|
||||
utf8 symbol[CURRENCY_SYMBOL_MAX_SIZE];
|
||||
int affix;
|
||||
int stringId;
|
||||
} rct_currency_spec;
|
||||
uint8 affix_unicode;
|
||||
utf8 symbol_unicode[CURRENCY_SYMBOL_MAX_SIZE];
|
||||
uint8 affix_ascii;
|
||||
char symbol_ascii[CURRENCY_SYMBOL_MAX_SIZE];
|
||||
rct_string_id stringId;
|
||||
} currency_descriptor;
|
||||
|
||||
// List of currency formats
|
||||
extern const rct_currency_spec g_currency_specs[CURRENCY_END];
|
||||
extern const currency_descriptor CurrencyDescriptors[CURRENCY_END];
|
||||
|
||||
#endif
|
||||
|
||||
@@ -173,6 +173,11 @@ int language_open(int id)
|
||||
gCurrentTTFFontSet = LanguagesDescriptors[id].font;
|
||||
if (!ttf_initialise()) {
|
||||
log_warning("Unable to initialise TrueType fonts.");
|
||||
|
||||
// Fall back to sprite font
|
||||
gUseTrueTypeFont = false;
|
||||
gCurrentTTFFontSet = nullptr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -345,9 +345,9 @@ void format_comma_separated_fixed_2dp(char **dest, long long value)
|
||||
|
||||
void format_currency(char **dest, long long value)
|
||||
{
|
||||
const rct_currency_spec *currencySpec = &g_currency_specs[gConfigGeneral.currency_format];
|
||||
const currency_descriptor *currencyDesc = &CurrencyDescriptors[gConfigGeneral.currency_format];
|
||||
|
||||
int rate = currencySpec->rate;
|
||||
int rate = currencyDesc->rate;
|
||||
value *= rate;
|
||||
|
||||
// Negative sign
|
||||
@@ -363,10 +363,15 @@ void format_currency(char **dest, long long value)
|
||||
}
|
||||
|
||||
// Currency symbol
|
||||
const utf8 *symbol = currencySpec->symbol;
|
||||
const utf8 *symbol = currencyDesc->symbol_unicode;
|
||||
uint8 affix = currencyDesc->affix_unicode;
|
||||
if (!font_supports_string(symbol, FONT_SIZE_MEDIUM)) {
|
||||
symbol = currencyDesc->symbol_ascii;
|
||||
affix = currencyDesc->affix_ascii;
|
||||
}
|
||||
|
||||
// Prefix
|
||||
if (currencySpec->affix == CURRENCY_PREFIX) {
|
||||
if (affix == CURRENCY_PREFIX) {
|
||||
safe_strncpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
@@ -374,7 +379,7 @@ void format_currency(char **dest, long long value)
|
||||
format_comma_separated_integer(dest, value);
|
||||
|
||||
// Currency symbol suffix
|
||||
if (currencySpec->affix == CURRENCY_SUFFIX) {
|
||||
if (affix == CURRENCY_SUFFIX) {
|
||||
safe_strncpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
@@ -382,9 +387,9 @@ void format_currency(char **dest, long long value)
|
||||
|
||||
void format_currency_2dp(char **dest, long long value)
|
||||
{
|
||||
const rct_currency_spec *currencySpec = &g_currency_specs[gConfigGeneral.currency_format];
|
||||
const currency_descriptor *currencyDesc = &CurrencyDescriptors[gConfigGeneral.currency_format];
|
||||
|
||||
int rate = currencySpec->rate;
|
||||
int rate = currencyDesc->rate;
|
||||
value *= rate;
|
||||
|
||||
// Negative sign
|
||||
@@ -394,10 +399,15 @@ void format_currency_2dp(char **dest, long long value)
|
||||
}
|
||||
|
||||
// Currency symbol
|
||||
const utf8 *symbol = currencySpec->symbol;
|
||||
const utf8 *symbol = currencyDesc->symbol_unicode;
|
||||
uint8 affix = currencyDesc->affix_unicode;
|
||||
if (!font_supports_string(symbol, FONT_SIZE_MEDIUM)) {
|
||||
symbol = currencyDesc->symbol_ascii;
|
||||
affix = currencyDesc->affix_ascii;
|
||||
}
|
||||
|
||||
// Prefix
|
||||
if (currencySpec->affix == CURRENCY_PREFIX) {
|
||||
if (affix == CURRENCY_PREFIX) {
|
||||
safe_strncpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
@@ -410,7 +420,7 @@ void format_currency_2dp(char **dest, long long value)
|
||||
}
|
||||
|
||||
// Currency symbol suffix
|
||||
if (currencySpec->affix == CURRENCY_SUFFIX) {
|
||||
if (affix == CURRENCY_SUFFIX) {
|
||||
safe_strncpy(*dest, symbol, CURRENCY_SYMBOL_MAX_SIZE);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
|
||||
@@ -2174,6 +2174,8 @@ enum {
|
||||
|
||||
STR_UI_SCALING_DESC = 5579,
|
||||
|
||||
STR_CZECH_KORUNA = 5580,
|
||||
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
STR_COUNT = 32768
|
||||
};
|
||||
|
||||
@@ -251,10 +251,13 @@ bool openrct2_initialise()
|
||||
audio_init();
|
||||
audio_populate_devices();
|
||||
}
|
||||
if (!language_open(gConfigGeneral.language))
|
||||
{
|
||||
log_fatal("Failed to open language, exiting.");
|
||||
return false;
|
||||
if (!language_open(gConfigGeneral.language)) {
|
||||
log_error("Failed to open configured language...");
|
||||
|
||||
if (!language_open(LANGUAGE_ENGLISH_UK)) {
|
||||
log_fatal("Failed to open fallback language...");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
http_init();
|
||||
|
||||
|
||||
@@ -803,7 +803,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
||||
|
||||
for (i = 0; i < num_items; i++) {
|
||||
gDropdownItemsFormat[i] = 1142;
|
||||
gDropdownItemsArgs[i] = g_currency_specs[i].stringId;
|
||||
gDropdownItemsArgs[i] = CurrencyDescriptors[i].stringId;
|
||||
}
|
||||
|
||||
window_options_show_dropdown(w, widget, num_items);
|
||||
@@ -1204,7 +1204,7 @@ static void window_options_invalidate(rct_window *w)
|
||||
|
||||
case WINDOW_OPTIONS_PAGE_CULTURE:
|
||||
// currency: pounds, dollars, etc. (10 total)
|
||||
RCT2_GLOBAL(0x013CE952 + 12, uint16) = g_currency_specs[gConfigGeneral.currency_format].stringId;
|
||||
RCT2_GLOBAL(0x013CE952 + 12, uint16) = CurrencyDescriptors[gConfigGeneral.currency_format].stringId;
|
||||
|
||||
// distance: metric/imperial
|
||||
RCT2_GLOBAL(0x013CE952 + 14, uint16) = STR_IMPERIAL + gConfigGeneral.measurement_format;
|
||||
|
||||
Reference in New Issue
Block a user