clang-format localisation

This commit is contained in:
clang-format 2018-06-22 23:01:56 +02:00 committed by Hielke Morsink
parent 17d2693422
commit 737d2c490c
19 changed files with 1232 additions and 947 deletions

View File

@ -7,12 +7,13 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include <cstdlib> #include "ConversionTables.h"
#include "../core/Util.hpp" #include "../core/Util.hpp"
#include "ConversionTables.h"
#include "FormatCodes.h" #include "FormatCodes.h"
#include <cstdlib>
// clang-format off // clang-format off
const encoding_convert_entry RCT2ToUnicodeTable[256] = const encoding_convert_entry RCT2ToUnicodeTable[256] =
{ {

View File

@ -7,14 +7,15 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include <algorithm>
#include <limits>
#include <stdexcept>
#include "../core/String.hpp" #include "../core/String.hpp"
#include "../core/Util.hpp" #include "../core/Util.hpp"
#include "ConversionTables.h" #include "ConversionTables.h"
#include "Language.h" #include "Language.h"
#include <algorithm>
#include <limits>
#include <stdexcept>
/** /**
* Decodes an RCT2 string to a wide char string still in the original code page. * Decodes an RCT2 string to a wide char string still in the original code page.
* An RCT2 string is a multi-byte string where every two-byte code point is preceeded with a byte value of 255. * An RCT2 string is a multi-byte string where every two-byte code point is preceeded with a byte value of 255.
@ -23,7 +24,7 @@ static std::wstring DecodeToWideChar(const std::string_view& src)
{ {
std::wstring decoded; std::wstring decoded;
decoded.reserve(src.size()); decoded.reserve(src.size());
for (auto it = src.begin(); it != src.end(); ) for (auto it = src.begin(); it != src.end();)
{ {
uint8_t c = *it++; uint8_t c = *it++;
if (c == 255) if (c == 255)
@ -88,7 +89,7 @@ static std::string DecodeToMultiByte(const std::string_view& src)
static std::string Encode(const std::string_view& src) static std::string Encode(const std::string_view& src)
{ {
std::string dst; std::string dst;
const utf8 * ch = src.data(); const utf8* ch = src.data();
int32_t codepoint; int32_t codepoint;
while ((codepoint = utf8_get_next(ch, &ch)) != 0) while ((codepoint = utf8_get_next(ch, &ch)) != 0)
{ {
@ -129,8 +130,7 @@ static int32_t GetCodePageForRCT2Language(RCT2LanguageId languageId)
} }
} }
template<typename TConvertFunc> template<typename TConvertFunc> static std::string DecodeConvertWithTable(const std::string_view& src, TConvertFunc func)
static std::string DecodeConvertWithTable(const std::string_view& src, TConvertFunc func)
{ {
auto decoded = DecodeToWideChar(src); auto decoded = DecodeToWideChar(src);
std::wstring u16; std::wstring u16;

View File

@ -7,9 +7,10 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include "Currency.h"
#include "../config/Config.h" #include "../config/Config.h"
#include "../util/Util.h" #include "../util/Util.h"
#include "Currency.h"
#include "StringIds.h" #include "StringIds.h"
// clang-format off // clang-format off
@ -40,6 +41,9 @@ void currency_load_custom_currency_config()
CurrencyDescriptors[CURRENCY_CUSTOM].affix_unicode = gConfigGeneral.custom_currency_affix; CurrencyDescriptors[CURRENCY_CUSTOM].affix_unicode = gConfigGeneral.custom_currency_affix;
if (gConfigGeneral.custom_currency_symbol != nullptr) if (gConfigGeneral.custom_currency_symbol != nullptr)
{ {
safe_strcpy(CurrencyDescriptors[CURRENCY_CUSTOM].symbol_unicode, gConfigGeneral.custom_currency_symbol, CURRENCY_SYMBOL_MAX_SIZE); safe_strcpy(
CurrencyDescriptors[CURRENCY_CUSTOM].symbol_unicode,
gConfigGeneral.custom_currency_symbol,
CURRENCY_SYMBOL_MAX_SIZE);
} }
} }

View File

@ -13,30 +13,32 @@
#include "../common.h" #include "../common.h"
// List of currencies // List of currencies
enum CURRENCY_TYPE { enum CURRENCY_TYPE
CURRENCY_POUNDS, // British Pound {
CURRENCY_DOLLARS, // US Dollar CURRENCY_POUNDS, // British Pound
CURRENCY_FRANC, // French Franc CURRENCY_DOLLARS, // US Dollar
CURRENCY_DEUTSCHMARK, // Deutsche Mark CURRENCY_FRANC, // French Franc
CURRENCY_YEN, // Japanese Yen CURRENCY_DEUTSCHMARK, // Deutsche Mark
CURRENCY_PESETA, // Spanish Peseta CURRENCY_YEN, // Japanese Yen
CURRENCY_LIRA, // Italian Lira CURRENCY_PESETA, // Spanish Peseta
CURRENCY_GUILDERS, // Dutch Gilder CURRENCY_LIRA, // Italian Lira
CURRENCY_KRONA, // Swedish Krona CURRENCY_GUILDERS, // Dutch Gilder
CURRENCY_EUROS, // Euro CURRENCY_KRONA, // Swedish Krona
CURRENCY_WON, // South Korean Won CURRENCY_EUROS, // Euro
CURRENCY_ROUBLE, // Russian Rouble CURRENCY_WON, // South Korean Won
CURRENCY_CZECH_KORUNA, // Czech koruna CURRENCY_ROUBLE, // Russian Rouble
CURRENCY_HKD, // Hong Kong Dollar CURRENCY_CZECH_KORUNA, // Czech koruna
CURRENCY_TWD, // New Taiwan Dollar CURRENCY_HKD, // Hong Kong Dollar
CURRENCY_YUAN, // Chinese Yuan CURRENCY_TWD, // New Taiwan Dollar
CURRENCY_YUAN, // Chinese Yuan
CURRENCY_CUSTOM, // Custom currency CURRENCY_CUSTOM, // Custom currency
CURRENCY_END // Last item CURRENCY_END // Last item
}; };
enum CURRENCY_AFFIX { enum CURRENCY_AFFIX
{
CURRENCY_PREFIX, CURRENCY_PREFIX,
CURRENCY_SUFFIX CURRENCY_SUFFIX
}; };
@ -45,7 +47,8 @@ enum CURRENCY_AFFIX {
#define CURRENCY_RATE_MAX_NUM_DIGITS 9 #define CURRENCY_RATE_MAX_NUM_DIGITS 9
// Currency format specification - inspired by OpenTTD // Currency format specification - inspired by OpenTTD
struct currency_descriptor { struct currency_descriptor
{
char isoCode[4]; char isoCode[4];
// Rate is relative to 0.10 GBP // Rate is relative to 0.10 GBP
int32_t rate; int32_t rate;

View File

@ -12,7 +12,8 @@
#include "../common.h" #include "../common.h"
enum { enum
{
MONTH_MARCH, MONTH_MARCH,
MONTH_APRIL, MONTH_APRIL,
MONTH_MAY, MONTH_MAY,
@ -25,14 +26,16 @@ enum {
MONTH_COUNT MONTH_COUNT
}; };
enum { enum
{
DATE_FORMAT_DAY_MONTH_YEAR, DATE_FORMAT_DAY_MONTH_YEAR,
DATE_FORMAT_MONTH_DAY_YEAR, DATE_FORMAT_MONTH_DAY_YEAR,
DATE_FORMAT_YEAR_MONTH_DAY, DATE_FORMAT_YEAR_MONTH_DAY,
DATE_FORMAT_YEAR_DAY_MONTH DATE_FORMAT_YEAR_DAY_MONTH
}; };
struct openrct_timeofday { struct openrct_timeofday
{
uint8_t second; uint8_t second;
uint8_t minute; uint8_t minute;
uint8_t hour; uint8_t hour;

View File

@ -7,16 +7,18 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include "FormatCodes.h"
#include "../common.h" #include "../common.h"
#include "../core/Util.hpp" #include "../core/Util.hpp"
#include "FormatCodes.h"
#include "Localisation.h" #include "Localisation.h"
#pragma region Format codes #pragma region Format codes
struct format_code_token { struct format_code_token
{
uint32_t code; uint32_t code;
const char *token; const char* token;
}; };
// clang-format off // clang-format off
@ -95,7 +97,7 @@ static constexpr const format_code_token format_code_tokens[] = {
}; };
// clang-format on // clang-format on
uint32_t format_get_code(const char *token) uint32_t format_get_code(const char* token)
{ {
for (uint32_t i = 0; i < Util::CountOf(format_code_tokens); i++) for (uint32_t i = 0; i < Util::CountOf(format_code_tokens); i++)
{ {
@ -105,7 +107,7 @@ uint32_t format_get_code(const char *token)
return 0; return 0;
} }
const char *format_get_token(uint32_t code) const char* format_get_token(uint32_t code)
{ {
for (uint32_t i = 0; i < Util::CountOf(format_code_tokens); i++) for (uint32_t i = 0; i < Util::CountOf(format_code_tokens); i++)
{ {
@ -117,24 +119,25 @@ const char *format_get_token(uint32_t code)
bool utf8_should_use_sprite_for_codepoint(int32_t codepoint) bool utf8_should_use_sprite_for_codepoint(int32_t codepoint)
{ {
switch (codepoint) { switch (codepoint)
case FORMAT_UP: {
case FORMAT_DOWN: case FORMAT_UP:
case FORMAT_LEFTGUILLEMET: case FORMAT_DOWN:
case FORMAT_TICK: case FORMAT_LEFTGUILLEMET:
case FORMAT_CROSS: case FORMAT_TICK:
case FORMAT_RIGHT: case FORMAT_CROSS:
case FORMAT_RIGHTGUILLEMET: case FORMAT_RIGHT:
case FORMAT_SMALLUP: case FORMAT_RIGHTGUILLEMET:
case FORMAT_SMALLDOWN: case FORMAT_SMALLUP:
case FORMAT_LEFT: case FORMAT_SMALLDOWN:
case FORMAT_OPENQUOTES: case FORMAT_LEFT:
case FORMAT_ENDQUOTES: case FORMAT_OPENQUOTES:
case UNICODE_DINGBATS_PLUS: case FORMAT_ENDQUOTES:
case UNICODE_DINGBATS_MINUS: case UNICODE_DINGBATS_PLUS:
return true; case UNICODE_DINGBATS_MINUS:
default: return true;
return false; default:
return false;
} }
} }

View File

@ -12,10 +12,11 @@
#include "../common.h" #include "../common.h"
uint32_t format_get_code(const char *token); uint32_t format_get_code(const char* token);
const char *format_get_token(uint32_t code); const char* format_get_token(uint32_t code);
enum { enum
{
// Font format codes // Font format codes
// The next byte specifies the X coordinate // The next byte specifies the X coordinate
@ -135,22 +136,22 @@ enum {
enum RCT2Polish enum RCT2Polish
{ {
RCT2_A_OGONEK_UC = 159, // 0x9F RCT2_A_OGONEK_UC = 159, // 0x9F
RCT2_C_ACUTE_UC = 162, // 0xA2 RCT2_C_ACUTE_UC = 162, // 0xA2
RCT2_E_OGONEK_UC = 166, // 0xA6 RCT2_E_OGONEK_UC = 166, // 0xA6
RCT2_N_ACUTE_UC = 198, // 0xC6 RCT2_N_ACUTE_UC = 198, // 0xC6
RCT2_L_STROKE_UC = 167, // 0xA7 RCT2_L_STROKE_UC = 167, // 0xA7
RCT2_S_ACUTE_UC = 208, // 0xD0 RCT2_S_ACUTE_UC = 208, // 0xD0
RCT2_Z_DOT_UC = 216, // 0xD8 RCT2_Z_DOT_UC = 216, // 0xD8
RCT2_Z_ACUTE_UC = 215, // 0xD7 RCT2_Z_ACUTE_UC = 215, // 0xD7
RCT2_A_OGONEK = 221, // 0xDD RCT2_A_OGONEK = 221, // 0xDD
RCT2_C_ACUTE = 222, // 0xDE RCT2_C_ACUTE = 222, // 0xDE
RCT2_E_OGONEK = 230, // 0xE6 RCT2_E_OGONEK = 230, // 0xE6
RCT2_N_ACUTE = 240, // 0xF0 RCT2_N_ACUTE = 240, // 0xF0
RCT2_L_STROKE = 247, // 0xF7 RCT2_L_STROKE = 247, // 0xF7
RCT2_S_ACUTE = 248, // 0xF8 RCT2_S_ACUTE = 248, // 0xF8
RCT2_Z_DOT = 253, // 0xFD RCT2_Z_DOT = 253, // 0xFD
RCT2_Z_ACUTE = 254, // 0xFE RCT2_Z_ACUTE = 254, // 0xFE
}; };
enum UnicodePolish enum UnicodePolish

View File

@ -7,18 +7,19 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include <stack>
#include "../Context.h" #include "../Context.h"
#include "../core/Path.hpp" #include "../core/Path.hpp"
#include "../core/String.hpp" #include "../core/String.hpp"
#include "../interface/Fonts.h"
#include "../interface/FontFamilies.h" #include "../interface/FontFamilies.h"
#include "../interface/Fonts.h"
#include "../object/ObjectManager.h" #include "../object/ObjectManager.h"
#include "../platform/platform.h" #include "../platform/platform.h"
#include "LanguagePack.h" #include "LanguagePack.h"
#include "Localisation.h" #include "Localisation.h"
#include "LocalisationService.h" #include "LocalisationService.h"
#include <stack>
// clang-format off // clang-format off
const language_descriptor LanguagesDescriptors[LANGUAGE_COUNT] = const language_descriptor LanguagesDescriptors[LANGUAGE_COUNT] =
{ {
@ -56,10 +57,10 @@ const utf8 BlackRightArrowString[] = { (utf8)(uint8_t)0xC2, (utf8)(uint8_t)0x
const utf8 CheckBoxMarkString[] = { (utf8)(uint8_t)0xE2, (utf8)(uint8_t)0x9C, (utf8)(uint8_t)0x93, (utf8)(uint8_t)0x00 }; const utf8 CheckBoxMarkString[] = { (utf8)(uint8_t)0xE2, (utf8)(uint8_t)0x9C, (utf8)(uint8_t)0x93, (utf8)(uint8_t)0x00 };
// clang-format on // clang-format on
void utf8_remove_format_codes(utf8 * text, bool allowcolours) void utf8_remove_format_codes(utf8* text, bool allowcolours)
{ {
const utf8 * ch = text; const utf8* ch = text;
utf8 * dstCh = text; utf8* dstCh = text;
int32_t codepoint; int32_t codepoint;
while ((codepoint = String::GetNextCodepoint(ch, &ch)) != 0) while ((codepoint = String::GetNextCodepoint(ch, &ch)) != 0)
{ {
@ -71,10 +72,10 @@ void utf8_remove_format_codes(utf8 * text, bool allowcolours)
*dstCh = 0; *dstCh = 0;
} }
uint8_t language_get_id_from_locale(const char * locale) uint8_t language_get_id_from_locale(const char* locale)
{ {
uint8_t i = 0; uint8_t i = 0;
for (const auto &langDesc : LanguagesDescriptors) for (const auto& langDesc : LanguagesDescriptors)
{ {
if (String::Equals(locale, langDesc.locale)) if (String::Equals(locale, langDesc.locale))
{ {
@ -85,7 +86,7 @@ uint8_t language_get_id_from_locale(const char * locale)
return LANGUAGE_UNDEFINED; return LANGUAGE_UNDEFINED;
} }
const char * language_get_string(rct_string_id id) const char* language_get_string(rct_string_id id)
{ {
const auto& localisationService = OpenRCT2::GetContext()->GetLocalisationService(); const auto& localisationService = OpenRCT2::GetContext()->GetLocalisationService();
return localisationService.GetString(id); return localisationService.GetString(id);
@ -107,17 +108,14 @@ bool language_open(int32_t id)
} }
} }
bool language_get_localised_scenario_strings(const utf8 *scenarioFilename, rct_string_id *outStringIds) bool language_get_localised_scenario_strings(const utf8* scenarioFilename, rct_string_id* outStringIds)
{ {
const auto& localisationService = OpenRCT2::GetContext()->GetLocalisationService(); const auto& localisationService = OpenRCT2::GetContext()->GetLocalisationService();
auto result = localisationService.GetLocalisedScenarioStrings(scenarioFilename); auto result = localisationService.GetLocalisedScenarioStrings(scenarioFilename);
outStringIds[0] = std::get<0>(result); outStringIds[0] = std::get<0>(result);
outStringIds[1] = std::get<1>(result); outStringIds[1] = std::get<1>(result);
outStringIds[2] = std::get<2>(result); outStringIds[2] = std::get<2>(result);
return return outStringIds[0] != STR_NONE || outStringIds[1] != STR_NONE || outStringIds[2] != STR_NONE;
outStringIds[0] != STR_NONE ||
outStringIds[1] != STR_NONE ||
outStringIds[2] != STR_NONE;
} }
void language_free_object_string(rct_string_id stringId) void language_free_object_string(rct_string_id stringId)
@ -126,13 +124,13 @@ void language_free_object_string(rct_string_id stringId)
localisationService.FreeObjectString(stringId); localisationService.FreeObjectString(stringId);
} }
rct_string_id language_get_object_override_string_id(const char * identifier, uint8_t index) rct_string_id language_get_object_override_string_id(const char* identifier, uint8_t index)
{ {
const auto& localisationService = OpenRCT2::GetContext()->GetLocalisationService(); const auto& localisationService = OpenRCT2::GetContext()->GetLocalisationService();
return localisationService.GetObjectOverrideStringId(identifier, index); return localisationService.GetObjectOverrideStringId(identifier, index);
} }
rct_string_id language_allocate_object_string(const std::string &target) rct_string_id language_allocate_object_string(const std::string& target)
{ {
auto& localisationService = OpenRCT2::GetContext()->GetLocalisationService(); auto& localisationService = OpenRCT2::GetContext()->GetLocalisationService();
return localisationService.AllocateObjectString(target); return localisationService.AllocateObjectString(target);

View File

@ -10,12 +10,14 @@
#ifndef _LANGUAGE_H_ #ifndef _LANGUAGE_H_
#define _LANGUAGE_H_ #define _LANGUAGE_H_
#include <string>
#include <string_view>
#include "../common.h" #include "../common.h"
#include "../drawing/Font.h" #include "../drawing/Font.h"
enum { #include <string>
#include <string_view>
enum
{
LANGUAGE_UNDEFINED, LANGUAGE_UNDEFINED,
LANGUAGE_ARABIC, LANGUAGE_ARABIC,
LANGUAGE_CATALAN, LANGUAGE_CATALAN,
@ -66,14 +68,15 @@ enum RCT2LanguageId
#include "../interface/FontFamilies.h" #include "../interface/FontFamilies.h"
struct language_descriptor { struct language_descriptor
const char *locale; {
const utf8 *english_name; const char* locale;
const utf8 *native_name; const utf8* english_name;
const utf8* native_name;
#if !defined(NO_TTF) #if !defined(NO_TTF)
TTFontFamily const * font_family; TTFontFamily const* font_family;
#else #else
void * font_family; void* font_family;
#endif #endif
RCT2LanguageId rct2_original_id; RCT2LanguageId rct2_original_id;
}; };
@ -86,25 +89,25 @@ extern const utf8 BlackLeftArrowString[];
extern const utf8 BlackRightArrowString[]; extern const utf8 BlackRightArrowString[];
extern const utf8 CheckBoxMarkString[]; extern const utf8 CheckBoxMarkString[];
uint8_t language_get_id_from_locale(const char * locale); uint8_t language_get_id_from_locale(const char* locale);
const char *language_get_string(rct_string_id id); const char* language_get_string(rct_string_id id);
bool language_open(int32_t id); bool language_open(int32_t id);
uint32_t utf8_get_next(const utf8 *char_ptr, const utf8 **nextchar_ptr); uint32_t utf8_get_next(const utf8* char_ptr, const utf8** nextchar_ptr);
utf8 *utf8_write_codepoint(utf8 *dst, uint32_t codepoint); utf8* utf8_write_codepoint(utf8* dst, uint32_t codepoint);
int32_t utf8_insert_codepoint(utf8 *dst, uint32_t codepoint); int32_t utf8_insert_codepoint(utf8* dst, uint32_t codepoint);
bool utf8_is_codepoint_start(const utf8 *text); bool utf8_is_codepoint_start(const utf8* text);
void utf8_remove_format_codes(utf8 *text, bool allowcolours); void utf8_remove_format_codes(utf8* text, bool allowcolours);
int32_t utf8_get_codepoint_length(int32_t codepoint); int32_t utf8_get_codepoint_length(int32_t codepoint);
int32_t utf8_length(const utf8 *text); int32_t utf8_length(const utf8* text);
wchar_t *utf8_to_widechar(const utf8 *src); wchar_t* utf8_to_widechar(const utf8* src);
utf8 *widechar_to_utf8(const wchar_t *src); utf8* widechar_to_utf8(const wchar_t* src);
std::string rct2_to_utf8(const std::string_view& src, RCT2LanguageId languageId); std::string rct2_to_utf8(const std::string_view& src, RCT2LanguageId languageId);
std::string utf8_to_rct2(const std::string_view& src); std::string utf8_to_rct2(const std::string_view& src);
bool language_get_localised_scenario_strings(const utf8 *scenarioFilename, rct_string_id *outStringIds); bool language_get_localised_scenario_strings(const utf8* scenarioFilename, rct_string_id* outStringIds);
void language_free_object_string(rct_string_id stringId); void language_free_object_string(rct_string_id stringId);
rct_string_id language_get_object_override_string_id(const char * identifier, uint8_t index); rct_string_id language_get_object_override_string_id(const char* identifier, uint8_t index);
rct_string_id language_allocate_object_string(const std::string &target); rct_string_id language_allocate_object_string(const std::string& target);
#endif #endif

View File

@ -7,35 +7,35 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include <algorithm> #include "LanguagePack.h"
#include <string>
#include <vector>
#include "../common.h" #include "../common.h"
#include "Localisation.h"
#include "../core/FileStream.hpp" #include "../core/FileStream.hpp"
#include "../core/Math.hpp" #include "../core/Math.hpp"
#include "../core/Memory.hpp" #include "../core/Memory.hpp"
#include "../core/String.hpp" #include "../core/String.hpp"
#include "../core/StringBuilder.hpp" #include "../core/StringBuilder.hpp"
#include "../core/StringReader.hpp" #include "../core/StringReader.hpp"
#include "LanguagePack.h" #include "Localisation.h"
#include <algorithm>
#include <string>
#include <vector>
// Don't try to load more than language files that exceed 64 MiB // Don't try to load more than language files that exceed 64 MiB
constexpr uint64_t MAX_LANGUAGE_SIZE = 64 * 1024 * 1024; constexpr uint64_t MAX_LANGUAGE_SIZE = 64 * 1024 * 1024;
constexpr uint64_t MAX_OBJECT_OVERRIDES = 4096; constexpr uint64_t MAX_OBJECT_OVERRIDES = 4096;
constexpr uint64_t MAX_SCENARIO_OVERRIDES = 4096; constexpr uint64_t MAX_SCENARIO_OVERRIDES = 4096;
constexpr rct_string_id ObjectOverrideBase = 0x6000; constexpr rct_string_id ObjectOverrideBase = 0x6000;
constexpr int32_t ObjectOverrideMaxStringCount = 3; constexpr int32_t ObjectOverrideMaxStringCount = 3;
constexpr rct_string_id ScenarioOverrideBase = 0x7000; constexpr rct_string_id ScenarioOverrideBase = 0x7000;
constexpr int32_t ScenarioOverrideMaxStringCount = 3; constexpr int32_t ScenarioOverrideMaxStringCount = 3;
struct ObjectOverride struct ObjectOverride
{ {
char name[8] = { 0 }; char name[8] = { 0 };
std::string strings[ObjectOverrideMaxStringCount]; std::string strings[ObjectOverrideMaxStringCount];
}; };
@ -49,24 +49,24 @@ class LanguagePack final : public ILanguagePack
{ {
private: private:
uint16_t const _id; uint16_t const _id;
std::vector<std::string> _strings; std::vector<std::string> _strings;
std::vector<ObjectOverride> _objectOverrides; std::vector<ObjectOverride> _objectOverrides;
std::vector<ScenarioOverride> _scenarioOverrides; std::vector<ScenarioOverride> _scenarioOverrides;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Parsing work data // Parsing work data
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
std::string _currentGroup; std::string _currentGroup;
ObjectOverride * _currentObjectOverride = nullptr; ObjectOverride* _currentObjectOverride = nullptr;
ScenarioOverride * _currentScenarioOverride = nullptr; ScenarioOverride* _currentScenarioOverride = nullptr;
public: public:
static LanguagePack * FromFile(uint16_t id, const utf8 * path) static LanguagePack* FromFile(uint16_t id, const utf8* path)
{ {
Guard::ArgumentNotNull(path); Guard::ArgumentNotNull(path);
// Load file directly into memory // Load file directly into memory
utf8 * fileData = nullptr; utf8* fileData = nullptr;
try try
{ {
FileStream fs = FileStream(path, FILE_MODE_OPEN); FileStream fs = FileStream(path, FILE_MODE_OPEN);
@ -81,7 +81,7 @@ public:
fs.Read(fileData, fileLength); fs.Read(fileData, fileLength);
fileData[fileLength] = '\0'; fileData[fileLength] = '\0';
} }
catch (const std::exception &ex) catch (const std::exception& ex)
{ {
Memory::Free(fileData); Memory::Free(fileData);
log_error("Unable to open %s: %s", path, ex.what()); log_error("Unable to open %s: %s", path, ex.what());
@ -89,18 +89,18 @@ public:
} }
// Parse the memory as text // Parse the memory as text
LanguagePack * result = FromText(id, fileData); LanguagePack* result = FromText(id, fileData);
Memory::Free(fileData); Memory::Free(fileData);
return result; return result;
} }
static LanguagePack * FromText(uint16_t id, const utf8 * text) static LanguagePack* FromText(uint16_t id, const utf8* text)
{ {
return new LanguagePack(id, text); return new LanguagePack(id, text);
} }
LanguagePack(uint16_t id, const utf8 * text) LanguagePack(uint16_t id, const utf8* text)
: _id(id) : _id(id)
{ {
Guard::ArgumentNotNull(text); Guard::ArgumentNotNull(text);
@ -135,7 +135,7 @@ public:
} }
} }
void SetString(rct_string_id stringId, const std::string &str) override void SetString(rct_string_id stringId, const std::string& str) override
{ {
if (_strings.size() >= (size_t)stringId) if (_strings.size() >= (size_t)stringId)
{ {
@ -143,7 +143,7 @@ public:
} }
} }
const utf8 * GetString(rct_string_id stringId) const override const utf8* GetString(rct_string_id stringId) const override
{ {
if (stringId >= ScenarioOverrideBase) if (stringId >= ScenarioOverrideBase)
{ {
@ -188,13 +188,13 @@ public:
} }
} }
rct_string_id GetObjectOverrideStringId(const char * objectIdentifier, uint8_t index) override rct_string_id GetObjectOverrideStringId(const char* objectIdentifier, uint8_t index) override
{ {
Guard::ArgumentNotNull(objectIdentifier); Guard::ArgumentNotNull(objectIdentifier);
Guard::Assert(index < ObjectOverrideMaxStringCount); Guard::Assert(index < ObjectOverrideMaxStringCount);
int32_t ooIndex = 0; int32_t ooIndex = 0;
for (const ObjectOverride &objectOverride : _objectOverrides) for (const ObjectOverride& objectOverride : _objectOverrides)
{ {
if (strncmp(objectOverride.name, objectIdentifier, 8) == 0) if (strncmp(objectOverride.name, objectIdentifier, 8) == 0)
{ {
@ -210,13 +210,13 @@ public:
return STR_NONE; return STR_NONE;
} }
rct_string_id GetScenarioOverrideStringId(const utf8 * scenarioFilename, uint8_t index) override rct_string_id GetScenarioOverrideStringId(const utf8* scenarioFilename, uint8_t index) override
{ {
Guard::ArgumentNotNull(scenarioFilename); Guard::ArgumentNotNull(scenarioFilename);
Guard::Assert(index < ScenarioOverrideMaxStringCount); Guard::Assert(index < ScenarioOverrideMaxStringCount);
int32_t ooIndex = 0; int32_t ooIndex = 0;
for (const ScenarioOverride &scenarioOverride : _scenarioOverrides) for (const ScenarioOverride& scenarioOverride : _scenarioOverrides)
{ {
if (String::Equals(scenarioOverride.filename.c_str(), scenarioFilename, true)) if (String::Equals(scenarioOverride.filename.c_str(), scenarioFilename, true))
{ {
@ -233,9 +233,9 @@ public:
} }
private: private:
ObjectOverride * GetObjectOverride(const std::string &objectIdentifier) ObjectOverride* GetObjectOverride(const std::string& objectIdentifier)
{ {
for (auto &oo : _objectOverrides) for (auto& oo : _objectOverrides)
{ {
if (strncmp(oo.name, objectIdentifier.c_str(), 8) == 0) if (strncmp(oo.name, objectIdentifier.c_str(), 8) == 0)
{ {
@ -245,9 +245,9 @@ private:
return nullptr; return nullptr;
} }
ScenarioOverride * GetScenarioOverride(const std::string &scenarioIdentifier) ScenarioOverride* GetScenarioOverride(const std::string& scenarioIdentifier)
{ {
for (auto &so : _scenarioOverrides) for (auto& so : _scenarioOverrides)
{ {
if (String::Equals(so.strings[0], scenarioIdentifier.c_str(), true)) if (String::Equals(so.strings[0], scenarioIdentifier.c_str(), true))
{ {
@ -267,9 +267,9 @@ private:
// Unsure at how the original game decides which entries to write resource strings to, but this could affect adding new // Unsure at how the original game decides which entries to write resource strings to, but this could affect adding new
// strings for the time being. Further investigation is required. // strings for the time being. Further investigation is required.
// //
// When reading the language files, the STR_XXXX part is read and XXXX becomes the string id number. Everything after the colon // When reading the language files, the STR_XXXX part is read and XXXX becomes the string id number. Everything after the
// and before the new line will be saved as the string. Tokens are written with inside curly braces {TOKEN}. // colon and before the new line will be saved as the string. Tokens are written with inside curly braces {TOKEN}. Use # at
// Use # at the beginning of a line to leave a comment. // the beginning of a line to leave a comment.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static bool IsWhitespace(codepoint_t codepoint) static bool IsWhitespace(codepoint_t codepoint)
@ -282,7 +282,7 @@ private:
return codepoint == '\r' || codepoint == '\n'; return codepoint == '\r' || codepoint == '\n';
} }
static void SkipWhitespace(IStringReader * reader) static void SkipWhitespace(IStringReader* reader)
{ {
codepoint_t codepoint; codepoint_t codepoint;
while (reader->TryPeek(&codepoint)) while (reader->TryPeek(&codepoint))
@ -298,7 +298,7 @@ private:
} }
} }
static void SkipNewLine(IStringReader * reader) static void SkipNewLine(IStringReader* reader)
{ {
codepoint_t codepoint; codepoint_t codepoint;
while (reader->TryPeek(&codepoint)) while (reader->TryPeek(&codepoint))
@ -314,10 +314,11 @@ private:
} }
} }
static void SkipToEndOfLine(IStringReader * reader) static void SkipToEndOfLine(IStringReader* reader)
{ {
codepoint_t codepoint; codepoint_t codepoint;
while (reader->TryPeek(&codepoint)) { while (reader->TryPeek(&codepoint))
{
if (codepoint != '\r' && codepoint != '\n') if (codepoint != '\r' && codepoint != '\n')
{ {
reader->Skip(); reader->Skip();
@ -329,36 +330,37 @@ private:
} }
} }
void ParseLine(IStringReader *reader) void ParseLine(IStringReader* reader)
{ {
SkipWhitespace(reader); SkipWhitespace(reader);
codepoint_t codepoint; codepoint_t codepoint;
if (reader->TryPeek(&codepoint)) if (reader->TryPeek(&codepoint))
{ {
switch (codepoint) { switch (codepoint)
case '#': {
SkipToEndOfLine(reader); case '#':
break; SkipToEndOfLine(reader);
case '[': break;
ParseGroupObject(reader); case '[':
break; ParseGroupObject(reader);
case '<': break;
ParseGroupScenario(reader); case '<':
break; ParseGroupScenario(reader);
case '\r': break;
case '\n': case '\r':
break; case '\n':
default: break;
ParseString(reader); default:
break; ParseString(reader);
break;
} }
SkipToEndOfLine(reader); SkipToEndOfLine(reader);
SkipNewLine(reader); SkipNewLine(reader);
} }
} }
void ParseGroupObject(IStringReader * reader) void ParseGroupObject(IStringReader* reader)
{ {
auto sb = StringBuilder(); auto sb = StringBuilder();
codepoint_t codepoint; codepoint_t codepoint;
@ -370,7 +372,8 @@ private:
bool closedCorrectly = false; bool closedCorrectly = false;
while (reader->TryPeek(&codepoint)) while (reader->TryPeek(&codepoint))
{ {
if (IsNewLine(codepoint)) break; if (IsNewLine(codepoint))
break;
reader->Skip(); reader->Skip();
if (codepoint == ']') if (codepoint == ']')
@ -407,7 +410,7 @@ private:
} }
} }
void ParseGroupScenario(IStringReader * reader) void ParseGroupScenario(IStringReader* reader)
{ {
auto sb = StringBuilder(); auto sb = StringBuilder();
codepoint_t codepoint; codepoint_t codepoint;
@ -419,7 +422,8 @@ private:
bool closedCorrectly = false; bool closedCorrectly = false;
while (reader->TryPeek(&codepoint)) while (reader->TryPeek(&codepoint))
{ {
if (IsNewLine(codepoint)) break; if (IsNewLine(codepoint))
break;
reader->Skip(); reader->Skip();
if (codepoint == '>') if (codepoint == '>')
@ -449,7 +453,7 @@ private:
} }
} }
void ParseString(IStringReader *reader) void ParseString(IStringReader* reader)
{ {
auto sb = StringBuilder(); auto sb = StringBuilder();
codepoint_t codepoint; codepoint_t codepoint;
@ -484,7 +488,7 @@ private:
reader->Skip(); reader->Skip();
// Validate identifier // Validate identifier
const utf8 * identifier = sb.GetBuffer(); const utf8* identifier = sb.GetBuffer();
int32_t stringId; int32_t stringId;
if (_currentGroup.empty()) if (_currentGroup.empty())
@ -497,14 +501,33 @@ private:
} }
else else
{ {
if (String::Equals(identifier, "STR_NAME")) { stringId = 0; } if (String::Equals(identifier, "STR_NAME"))
else if (String::Equals(identifier, "STR_DESC")) { stringId = 1; } {
else if (String::Equals(identifier, "STR_CPTY")) { stringId = 2; } stringId = 0;
}
else if (String::Equals(identifier, "STR_DESC"))
{
stringId = 1;
}
else if (String::Equals(identifier, "STR_CPTY"))
{
stringId = 2;
}
else if (String::Equals(identifier, "STR_SCNR")) { stringId = 0; } else if (String::Equals(identifier, "STR_SCNR"))
else if (String::Equals(identifier, "STR_PARK")) { stringId = 1; } {
else if (String::Equals(identifier, "STR_DTLS")) { stringId = 2; } stringId = 0;
else { }
else if (String::Equals(identifier, "STR_PARK"))
{
stringId = 1;
}
else if (String::Equals(identifier, "STR_DTLS"))
{
stringId = 2;
}
else
{
// Ignore line entirely // Ignore line entirely
return; return;
} }
@ -565,7 +588,7 @@ private:
} }
} }
bool ParseToken(IStringReader * reader, uint32_t * token, bool * isByte) bool ParseToken(IStringReader* reader, uint32_t* token, bool* isByte)
{ {
auto sb = StringBuilder(); auto sb = StringBuilder();
codepoint_t codepoint; codepoint_t codepoint;
@ -575,17 +598,20 @@ private:
while (reader->TryPeek(&codepoint)) while (reader->TryPeek(&codepoint))
{ {
if (IsNewLine(codepoint)) return false; if (IsNewLine(codepoint))
if (IsWhitespace(codepoint)) return false; return false;
if (IsWhitespace(codepoint))
return false;
reader->Skip(); reader->Skip();
if (codepoint == '}') break; if (codepoint == '}')
break;
sb.Append(codepoint); sb.Append(codepoint);
} }
const utf8 * tokenName = sb.GetBuffer(); const utf8* tokenName = sb.GetBuffer();
*token = format_get_code(tokenName); *token = format_get_code(tokenName);
*isByte = false; *isByte = false;
@ -606,13 +632,13 @@ private:
namespace LanguagePackFactory namespace LanguagePackFactory
{ {
ILanguagePack * FromFile(uint16_t id, const utf8 * path) ILanguagePack* FromFile(uint16_t id, const utf8* path)
{ {
auto languagePack = LanguagePack::FromFile(id, path); auto languagePack = LanguagePack::FromFile(id, path);
return languagePack; return languagePack;
} }
ILanguagePack * FromText(uint16_t id, const utf8 * text) ILanguagePack* FromText(uint16_t id, const utf8* text)
{ {
auto languagePack = LanguagePack::FromText(id, text); auto languagePack = LanguagePack::FromText(id, text);
return languagePack; return languagePack;

View File

@ -9,9 +9,10 @@
#pragma once #pragma once
#include <string>
#include "../common.h" #include "../common.h"
#include <string>
interface ILanguagePack interface ILanguagePack
{ {
virtual ~ILanguagePack() = default; virtual ~ILanguagePack() = default;
@ -19,15 +20,15 @@ interface ILanguagePack
virtual uint16_t GetId() const abstract; virtual uint16_t GetId() const abstract;
virtual uint32_t GetCount() const abstract; virtual uint32_t GetCount() const abstract;
virtual void RemoveString(rct_string_id stringId) abstract; virtual void RemoveString(rct_string_id stringId) abstract;
virtual void SetString(rct_string_id stringId, const std::string &str) abstract; virtual void SetString(rct_string_id stringId, const std::string& str) abstract;
virtual const utf8 * GetString(rct_string_id stringId) const abstract; virtual const utf8* GetString(rct_string_id stringId) const abstract;
virtual rct_string_id GetObjectOverrideStringId(const char * objectIdentifier, uint8_t index) abstract; virtual rct_string_id GetObjectOverrideStringId(const char* objectIdentifier, uint8_t index) abstract;
virtual rct_string_id GetScenarioOverrideStringId(const utf8 * scenarioFilename, uint8_t index) abstract; virtual rct_string_id GetScenarioOverrideStringId(const utf8* scenarioFilename, uint8_t index) abstract;
}; };
namespace LanguagePackFactory namespace LanguagePackFactory
{ {
ILanguagePack * FromFile(uint16_t id, const utf8 * path); ILanguagePack* FromFile(uint16_t id, const utf8* path);
ILanguagePack * FromText(uint16_t id, const utf8 * text); ILanguagePack* FromText(uint16_t id, const utf8* text);
} } // namespace LanguagePackFactory

View File

@ -7,12 +7,13 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include <time.h>
#include "../Game.h" #include "../Game.h"
#include "../core/Math.hpp" #include "../core/Math.hpp"
#include "Date.h" #include "Date.h"
#include "StringIds.h" #include "StringIds.h"
#include <time.h>
uint16_t gDateMonthTicks; uint16_t gDateMonthTicks;
uint16_t gDateMonthsElapsed; uint16_t gDateMonthsElapsed;
@ -89,7 +90,7 @@ void date_update()
void date_update_real_time_of_day() void date_update_real_time_of_day()
{ {
time_t timestamp = time(nullptr); time_t timestamp = time(nullptr);
struct tm *now = localtime(&timestamp); struct tm* now = localtime(&timestamp);
gRealTimeOfDay.second = now->tm_sec; gRealTimeOfDay.second = now->tm_sec;
gRealTimeOfDay.minute = now->tm_min; gRealTimeOfDay.minute = now->tm_min;

File diff suppressed because it is too large Load Diff

View File

@ -10,14 +10,14 @@
#ifndef LOCALISATION_H #ifndef LOCALISATION_H
#define LOCALISATION_H #define LOCALISATION_H
#include <cstring> #include "../management/Marketing.h"
#include "Currency.h" #include "Currency.h"
#include "Date.h" #include "Date.h"
#include "FormatCodes.h" #include "FormatCodes.h"
#include "Language.h" #include "Language.h"
#include "StringIds.h" #include "StringIds.h"
#include "../management/Marketing.h"
#include <cstring>
bool utf8_is_format_code(int32_t codepoint); bool utf8_is_format_code(int32_t codepoint);
bool utf8_is_colour_code(int32_t codepoint); bool utf8_is_colour_code(int32_t codepoint);
@ -25,21 +25,21 @@ bool utf8_should_use_sprite_for_codepoint(int32_t codepoint);
int32_t utf8_get_format_code_arg_length(int32_t codepoint); int32_t utf8_get_format_code_arg_length(int32_t codepoint);
void utf8_remove_formatting(utf8* string, bool allowColours); void utf8_remove_formatting(utf8* string, bool allowColours);
void format_string(char *dest, size_t size, rct_string_id format, void *args); void format_string(char* dest, size_t size, rct_string_id format, void* args);
void format_string_raw(char *dest, size_t size, char *src, void *args); void format_string_raw(char* dest, size_t size, char* src, void* args);
void format_string_to_upper(char *dest, size_t size, rct_string_id format, void *args); void format_string_to_upper(char* dest, size_t size, rct_string_id format, void* args);
void generate_string_file(); void generate_string_file();
utf8 *get_string_end(const utf8 *text); utf8* get_string_end(const utf8* text);
size_t get_string_size(const utf8 *text); size_t get_string_size(const utf8* text);
int32_t get_string_length(const utf8 *text); int32_t get_string_length(const utf8* text);
// The maximum number of characters allowed for string/money conversions (anything above will risk integer overflow issues) // The maximum number of characters allowed for string/money conversions (anything above will risk integer overflow issues)
#define MONEY_STRING_MAXLENGTH 14 #define MONEY_STRING_MAXLENGTH 14
money32 string_to_money(const char* string_to_monetise); money32 string_to_money(const char* string_to_monetise);
void money_to_string(money32 amount, char * buffer_to_put_value_to, size_t buffer_len, bool forceDecimals); void money_to_string(money32 amount, char* buffer_to_put_value_to, size_t buffer_len, bool forceDecimals);
void user_string_clear_all(); void user_string_clear_all();
rct_string_id user_string_allocate(int32_t base, const utf8 *text); rct_string_id user_string_allocate(int32_t base, const utf8* text);
void user_string_free(rct_string_id id); void user_string_free(rct_string_id id);
bool is_user_string_id(rct_string_id stringId); bool is_user_string_id(rct_string_id stringId);
@ -47,19 +47,20 @@ bool is_user_string_id(rct_string_id stringId);
#define USER_STRING_MAX_LENGTH 32 #define USER_STRING_MAX_LENGTH 32
#define USER_STRING_START 0x8000 #define USER_STRING_START 0x8000
#define USER_STRING_END 0x8FFF #define USER_STRING_END 0x8FFF
#define REAL_NAME_START 0xA000 #define REAL_NAME_START 0xA000
#define REAL_NAME_END 0xDFFF #define REAL_NAME_END 0xDFFF
// Constants used by user_string_allocate // Constants used by user_string_allocate
enum { enum
{
USER_STRING_HIGH_ID_NUMBER = 1 << 2, USER_STRING_HIGH_ID_NUMBER = 1 << 2,
USER_STRING_DUPLICATION_PERMITTED = 1 << 7 USER_STRING_DUPLICATION_PERMITTED = 1 << 7
}; };
// Real name data // Real name data
extern const char real_name_initials[16]; extern const char real_name_initials[16];
extern const char *real_names[1024]; extern const char* real_names[1024];
extern utf8 gUserStrings[MAX_USER_STRINGS][USER_STRING_MAX_LENGTH]; extern utf8 gUserStrings[MAX_USER_STRINGS][USER_STRING_MAX_LENGTH];
extern char gCommonStringFormatBuffer[256]; extern char gCommonStringFormatBuffer[256];
@ -77,20 +78,25 @@ extern const rct_string_id DateDayNames[31];
extern const rct_string_id DateGameMonthNames[MONTH_COUNT]; extern const rct_string_id DateGameMonthNames[MONTH_COUNT];
extern const rct_string_id DateGameShortMonthNames[MONTH_COUNT]; extern const rct_string_id DateGameShortMonthNames[MONTH_COUNT];
[[maybe_unused]] static inline void set_format_arg_body(uint8_t *args, size_t offset, uintptr_t value, size_t size) [[maybe_unused]] static inline void set_format_arg_body(uint8_t* args, size_t offset, uintptr_t value, size_t size)
{ {
memcpy(args + offset, &value, size); memcpy(args + offset, &value, size);
} }
#define set_format_arg(offset, type, value) \ #define set_format_arg(offset, type, value) \
do { static_assert(sizeof(type) <= sizeof(uintptr_t), "Type too large"); \ do \
set_format_arg_body(gCommonFormatArgs, offset, (uintptr_t)(value), sizeof(type)); } while (false) { \
static_assert(sizeof(type) <= sizeof(uintptr_t), "Type too large"); \
set_format_arg_body(gCommonFormatArgs, offset, (uintptr_t)(value), sizeof(type)); \
} while (false)
#define set_format_arg_on(args, offset, type, value) \ #define set_format_arg_on(args, offset, type, value) set_format_arg_body(args, offset, (uintptr_t)(value), sizeof(type))
set_format_arg_body(args, offset, (uintptr_t)(value), sizeof(type))
#define set_map_tooltip_format_arg(offset, type, value) \ #define set_map_tooltip_format_arg(offset, type, value) \
do { static_assert(sizeof(type) <= sizeof(uintptr_t), "Type too large"); \ do \
set_format_arg_body(gMapTooltipFormatArgs, offset, (uintptr_t)(value), sizeof(type)); } while (false) { \
static_assert(sizeof(type) <= sizeof(uintptr_t), "Type too large"); \
set_format_arg_body(gMapTooltipFormatArgs, offset, (uintptr_t)(value), sizeof(type)); \
} while (false)
#endif #endif

View File

@ -7,17 +7,19 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include <stdexcept> #include "LocalisationService.h"
#include "../Context.h" #include "../Context.h"
#include "../PlatformEnvironment.h"
#include "../core/Path.hpp" #include "../core/Path.hpp"
#include "../interface/Fonts.h" #include "../interface/Fonts.h"
#include "../object/ObjectManager.h" #include "../object/ObjectManager.h"
#include "../PlatformEnvironment.h"
#include "Language.h" #include "Language.h"
#include "LanguagePack.h" #include "LanguagePack.h"
#include "LocalisationService.h"
#include "StringIds.h" #include "StringIds.h"
#include <stdexcept>
using namespace OpenRCT2; using namespace OpenRCT2;
using namespace OpenRCT2::Localisation; using namespace OpenRCT2::Localisation;
@ -27,7 +29,8 @@ static constexpr uint16_t MAX_OBJECT_CACHED_STRINGS = 2048;
LocalisationService::LocalisationService(const std::shared_ptr<IPlatformEnvironment>& env) LocalisationService::LocalisationService(const std::shared_ptr<IPlatformEnvironment>& env)
: _env(env) : _env(env)
{ {
for (rct_string_id stringId = NONSTEX_BASE_STRING_ID + MAX_OBJECT_CACHED_STRINGS; stringId >= NONSTEX_BASE_STRING_ID; stringId--) for (rct_string_id stringId = NONSTEX_BASE_STRING_ID + MAX_OBJECT_CACHED_STRINGS; stringId >= NONSTEX_BASE_STRING_ID;
stringId--)
{ {
_availableObjectStringIds.push(stringId); _availableObjectStringIds.push(stringId);
} }
@ -38,9 +41,9 @@ LocalisationService::~LocalisationService()
{ {
} }
const char * LocalisationService::GetString(rct_string_id id) const const char* LocalisationService::GetString(rct_string_id id) const
{ {
const char * result = nullptr; const char* result = nullptr;
if (id == STR_EMPTY) if (id == STR_EMPTY)
{ {
result = ""; result = "";
@ -83,7 +86,8 @@ void LocalisationService::OpenLanguage(int32_t id, IObjectManager& objectManager
if (id != LANGUAGE_ENGLISH_UK) if (id != LANGUAGE_ENGLISH_UK)
{ {
filename = GetLanguagePath(LANGUAGE_ENGLISH_UK); filename = GetLanguagePath(LANGUAGE_ENGLISH_UK);
_languageFallback = std::unique_ptr<ILanguagePack>(LanguagePackFactory::FromFile(LANGUAGE_ENGLISH_UK, filename.c_str())); _languageFallback
= std::unique_ptr<ILanguagePack>(LanguagePackFactory::FromFile(LANGUAGE_ENGLISH_UK, filename.c_str()));
} }
filename = GetLanguagePath(id); filename = GetLanguagePath(id);
@ -109,7 +113,8 @@ void LocalisationService::CloseLanguages()
_currentLanguage = LANGUAGE_UNDEFINED; _currentLanguage = LANGUAGE_UNDEFINED;
} }
std::tuple<rct_string_id, rct_string_id, rct_string_id> LocalisationService::GetLocalisedScenarioStrings(const std::string& scenarioFilename) const std::tuple<rct_string_id, rct_string_id, rct_string_id>
LocalisationService::GetLocalisedScenarioStrings(const std::string& scenarioFilename) const
{ {
auto result0 = _languageCurrent->GetScenarioOverrideStringId(scenarioFilename.c_str(), 0); auto result0 = _languageCurrent->GetScenarioOverrideStringId(scenarioFilename.c_str(), 0);
auto result1 = _languageCurrent->GetScenarioOverrideStringId(scenarioFilename.c_str(), 1); auto result1 = _languageCurrent->GetScenarioOverrideStringId(scenarioFilename.c_str(), 1);
@ -117,7 +122,7 @@ std::tuple<rct_string_id, rct_string_id, rct_string_id> LocalisationService::Get
return std::make_tuple(result0, result1, result2); return std::make_tuple(result0, result1, result2);
} }
rct_string_id LocalisationService::GetObjectOverrideStringId(const char * identifier, uint8_t index) const rct_string_id LocalisationService::GetObjectOverrideStringId(const char* identifier, uint8_t index) const
{ {
if (_languageCurrent == nullptr) if (_languageCurrent == nullptr)
{ {

View File

@ -9,11 +9,12 @@
#pragma once #pragma once
#include "../common.h"
#include <memory> #include <memory>
#include <stack> #include <stack>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include "../common.h"
interface ILanguagePack; interface ILanguagePack;
interface IObjectManager; interface IObjectManager;
@ -36,16 +37,26 @@ namespace OpenRCT2::Localisation
std::stack<rct_string_id> _availableObjectStringIds; std::stack<rct_string_id> _availableObjectStringIds;
public: public:
int32_t GetCurrentLanguage() const { return _currentLanguage; } int32_t GetCurrentLanguage() const
bool UseTrueTypeFont() const { return _useTrueTypeFont; } {
void UseTrueTypeFont(bool value) { _useTrueTypeFont = value; } return _currentLanguage;
}
bool UseTrueTypeFont() const
{
return _useTrueTypeFont;
}
void UseTrueTypeFont(bool value)
{
_useTrueTypeFont = value;
}
LocalisationService(const std::shared_ptr<IPlatformEnvironment>& env); LocalisationService(const std::shared_ptr<IPlatformEnvironment>& env);
~LocalisationService(); ~LocalisationService();
const char * GetString(rct_string_id id) const; const char* GetString(rct_string_id id) const;
std::tuple<rct_string_id, rct_string_id, rct_string_id> GetLocalisedScenarioStrings(const std::string& scenarioFilename) const; std::tuple<rct_string_id, rct_string_id, rct_string_id>
rct_string_id GetObjectOverrideStringId(const char * identifier, uint8_t index) const; GetLocalisedScenarioStrings(const std::string& scenarioFilename) const;
rct_string_id GetObjectOverrideStringId(const char* identifier, uint8_t index) const;
std::string GetLanguagePath(uint32_t languageId) const; std::string GetLanguagePath(uint32_t languageId) const;
void OpenLanguage(int32_t id, IObjectManager& objectManager); void OpenLanguage(int32_t id, IObjectManager& objectManager);
@ -53,7 +64,7 @@ namespace OpenRCT2::Localisation
rct_string_id AllocateObjectString(const std::string& target); rct_string_id AllocateObjectString(const std::string& target);
void FreeObjectString(rct_string_id stringId); void FreeObjectString(rct_string_id stringId);
}; };
} } // namespace OpenRCT2::Localisation
// Legacy getters // Legacy getters
// TODO Remove usages of these and instead call via shared reference // TODO Remove usages of these and instead call via shared reference

File diff suppressed because it is too large Load Diff

View File

@ -8,26 +8,37 @@
*****************************************************************************/ *****************************************************************************/
#include "Localisation.h" #include "Localisation.h"
#include <wchar.h> #include <wchar.h>
uint32_t utf8_get_next(const utf8 *char_ptr, const utf8 **nextchar_ptr) uint32_t utf8_get_next(const utf8* char_ptr, const utf8** nextchar_ptr)
{ {
int32_t result; int32_t result;
int32_t numBytes; int32_t numBytes;
if (!(char_ptr[0] & 0x80)) { if (!(char_ptr[0] & 0x80))
{
result = char_ptr[0]; result = char_ptr[0];
numBytes = 1; numBytes = 1;
} else if ((char_ptr[0] & 0xE0) == 0xC0) { }
else if ((char_ptr[0] & 0xE0) == 0xC0)
{
result = ((char_ptr[0] & 0x1F) << 6) | (char_ptr[1] & 0x3F); result = ((char_ptr[0] & 0x1F) << 6) | (char_ptr[1] & 0x3F);
numBytes = 2; numBytes = 2;
} else if ((char_ptr[0] & 0xF0) == 0xE0) { }
else if ((char_ptr[0] & 0xF0) == 0xE0)
{
result = ((char_ptr[0] & 0x0F) << 12) | ((char_ptr[1] & 0x3F) << 6) | (char_ptr[2] & 0x3F); result = ((char_ptr[0] & 0x0F) << 12) | ((char_ptr[1] & 0x3F) << 6) | (char_ptr[2] & 0x3F);
numBytes = 3; numBytes = 3;
} else if ((char_ptr[0] & 0xF8) == 0xF0) { }
result = ((char_ptr[0] & 0x07) << 18) | ((char_ptr[1] & 0x3F) << 12) | ((char_ptr[1] & 0x3F) << 6) | (char_ptr[2] & 0x3F); else if ((char_ptr[0] & 0xF8) == 0xF0)
{
result
= ((char_ptr[0] & 0x07) << 18) | ((char_ptr[1] & 0x3F) << 12) | ((char_ptr[1] & 0x3F) << 6) | (char_ptr[2] & 0x3F);
numBytes = 4; numBytes = 4;
} else { }
else
{
// TODO 4 bytes // TODO 4 bytes
result = ' '; result = ' ';
numBytes = 1; numBytes = 1;
@ -38,21 +49,28 @@ uint32_t utf8_get_next(const utf8 *char_ptr, const utf8 **nextchar_ptr)
return result; return result;
} }
utf8 *utf8_write_codepoint(utf8 *dst, uint32_t codepoint) utf8* utf8_write_codepoint(utf8* dst, uint32_t codepoint)
{ {
if (codepoint <= 0x7F) { if (codepoint <= 0x7F)
{
dst[0] = (utf8)codepoint; dst[0] = (utf8)codepoint;
return dst + 1; return dst + 1;
} else if (codepoint <= 0x7FF) { }
else if (codepoint <= 0x7FF)
{
dst[0] = 0xC0 | ((codepoint >> 6) & 0x1F); dst[0] = 0xC0 | ((codepoint >> 6) & 0x1F);
dst[1] = 0x80 | (codepoint & 0x3F); dst[1] = 0x80 | (codepoint & 0x3F);
return dst + 2; return dst + 2;
} else if (codepoint <= 0xFFFF) { }
else if (codepoint <= 0xFFFF)
{
dst[0] = 0xE0 | ((codepoint >> 12) & 0x0F); dst[0] = 0xE0 | ((codepoint >> 12) & 0x0F);
dst[1] = 0x80 | ((codepoint >> 6) & 0x3F); dst[1] = 0x80 | ((codepoint >> 6) & 0x3F);
dst[2] = 0x80 | (codepoint & 0x3F); dst[2] = 0x80 | (codepoint & 0x3F);
return dst + 3; return dst + 3;
} else { }
else
{
dst[0] = 0xF0 | ((codepoint >> 18) & 0x07); dst[0] = 0xF0 | ((codepoint >> 18) & 0x07);
dst[1] = 0x80 | ((codepoint >> 12) & 0x3F); dst[1] = 0x80 | ((codepoint >> 12) & 0x3F);
dst[2] = 0x80 | ((codepoint >> 6) & 0x3F); dst[2] = 0x80 | ((codepoint >> 6) & 0x3F);
@ -65,31 +83,40 @@ utf8 *utf8_write_codepoint(utf8 *dst, uint32_t codepoint)
* Inserts the given codepoint at the given address, shifting all characters after along. * Inserts the given codepoint at the given address, shifting all characters after along.
* @returns the size of the inserted codepoint. * @returns the size of the inserted codepoint.
*/ */
int32_t utf8_insert_codepoint(utf8 *dst, uint32_t codepoint) int32_t utf8_insert_codepoint(utf8* dst, uint32_t codepoint)
{ {
int32_t shift = utf8_get_codepoint_length(codepoint); int32_t shift = utf8_get_codepoint_length(codepoint);
utf8 *endPoint = get_string_end(dst); utf8* endPoint = get_string_end(dst);
memmove(dst + shift, dst, endPoint - dst + 1); memmove(dst + shift, dst, endPoint - dst + 1);
utf8_write_codepoint(dst, codepoint); utf8_write_codepoint(dst, codepoint);
return shift; return shift;
} }
bool utf8_is_codepoint_start(const utf8 *text) bool utf8_is_codepoint_start(const utf8* text)
{ {
if ((text[0] & 0x80) == 0) return true; if ((text[0] & 0x80) == 0)
if ((text[0] & 0xC0) == 0xC0) return true; return true;
if ((text[0] & 0xC0) == 0xC0)
return true;
return false; return false;
} }
int32_t utf8_get_codepoint_length(int32_t codepoint) int32_t utf8_get_codepoint_length(int32_t codepoint)
{ {
if (codepoint <= 0x7F) { if (codepoint <= 0x7F)
{
return 1; return 1;
} else if (codepoint <= 0x7FF) { }
else if (codepoint <= 0x7FF)
{
return 2; return 2;
} else if (codepoint <= 0xFFFF) { }
else if (codepoint <= 0xFFFF)
{
return 3; return 3;
} else { }
else
{
return 4; return 4;
} }
} }
@ -98,28 +125,33 @@ int32_t utf8_get_codepoint_length(int32_t codepoint)
* Gets the number of characters / codepoints in a UTF-8 string (not necessarily 1:1 with bytes and not including null * Gets the number of characters / codepoints in a UTF-8 string (not necessarily 1:1 with bytes and not including null
* terminator). * terminator).
*/ */
int32_t utf8_length(const utf8 *text) int32_t utf8_length(const utf8* text)
{ {
const utf8 *ch = text; const utf8* ch = text;
int32_t count = 0; int32_t count = 0;
while (utf8_get_next(ch, &ch) != 0) { while (utf8_get_next(ch, &ch) != 0)
{
count++; count++;
} }
return count; return count;
} }
wchar_t *utf8_to_widechar(const utf8 *src) wchar_t* utf8_to_widechar(const utf8* src)
{ {
wchar_t * result = (wchar_t *)malloc((utf8_length(src) + 1) * sizeof(wchar_t)); wchar_t* result = (wchar_t*)malloc((utf8_length(src) + 1) * sizeof(wchar_t));
wchar_t *dst = result; wchar_t* dst = result;
const utf8 *ch = src; const utf8* ch = src;
int32_t codepoint; int32_t codepoint;
while ((codepoint = utf8_get_next(ch, &ch)) != 0) { while ((codepoint = utf8_get_next(ch, &ch)) != 0)
if ((uint32_t)codepoint > 0xFFFF) { {
if ((uint32_t)codepoint > 0xFFFF)
{
*dst++ = '?'; *dst++ = '?';
} else { }
else
{
*dst++ = codepoint; *dst++ = codepoint;
} }
} }
@ -128,30 +160,31 @@ wchar_t *utf8_to_widechar(const utf8 *src)
return result; return result;
} }
utf8 *widechar_to_utf8(const wchar_t *src) utf8* widechar_to_utf8(const wchar_t* src)
{ {
utf8 *result = (utf8 *)malloc((wcslen(src) * 4) + 1); utf8* result = (utf8*)malloc((wcslen(src) * 4) + 1);
utf8 *dst = result; utf8* dst = result;
for (; *src != 0; src++) { for (; *src != 0; src++)
{
dst = utf8_write_codepoint(dst, *src); dst = utf8_write_codepoint(dst, *src);
} }
*dst++ = 0; *dst++ = 0;
size_t size = (size_t)(dst - result); size_t size = (size_t)(dst - result);
return (utf8 *)realloc(result, size); return (utf8*)realloc(result, size);
} }
/** /**
* Returns a pointer to the null terminator of the given UTF-8 string. * Returns a pointer to the null terminator of the given UTF-8 string.
*/ */
utf8 *get_string_end(const utf8 *text) utf8* get_string_end(const utf8* text)
{ {
int32_t codepoint; int32_t codepoint;
const utf8 *ch = text; const utf8* ch = text;
while ((codepoint = utf8_get_next(ch, &ch)) != 0) { while ((codepoint = utf8_get_next(ch, &ch)) != 0)
{
int32_t argLength = utf8_get_format_code_arg_length(codepoint); int32_t argLength = utf8_get_format_code_arg_length(codepoint);
ch += argLength; ch += argLength;
} }
@ -161,7 +194,7 @@ utf8 *get_string_end(const utf8 *text)
/** /**
* Return the number of bytes (including the null terminator) in the given UTF-8 string. * Return the number of bytes (including the null terminator) in the given UTF-8 string.
*/ */
size_t get_string_size(const utf8 *text) size_t get_string_size(const utf8* text)
{ {
return get_string_end(text) - text + 1; return get_string_end(text) - text + 1;
} }
@ -169,16 +202,20 @@ size_t get_string_size(const utf8 *text)
/** /**
* Return the number of visible characters (excludes format codes) in the given UTF-8 string. * Return the number of visible characters (excludes format codes) in the given UTF-8 string.
*/ */
int32_t get_string_length(const utf8 *text) int32_t get_string_length(const utf8* text)
{ {
int32_t codepoint; int32_t codepoint;
const utf8 *ch = text; const utf8* ch = text;
int32_t count = 0; int32_t count = 0;
while ((codepoint = utf8_get_next(ch, &ch)) != 0) { while ((codepoint = utf8_get_next(ch, &ch)) != 0)
if (utf8_is_format_code(codepoint)) { {
if (utf8_is_format_code(codepoint))
{
ch += utf8_get_format_code_arg_length(codepoint); ch += utf8_get_format_code_arg_length(codepoint);
} else { }
else
{
count++; count++;
} }
} }
@ -187,32 +224,38 @@ int32_t get_string_length(const utf8 *text)
int32_t utf8_get_format_code_arg_length(int32_t codepoint) int32_t utf8_get_format_code_arg_length(int32_t codepoint)
{ {
switch (codepoint) { switch (codepoint)
case FORMAT_MOVE_X: {
case FORMAT_ADJUST_PALETTE: case FORMAT_MOVE_X:
case 3: case FORMAT_ADJUST_PALETTE:
case 4: case 3:
return 1; case 4:
case FORMAT_NEWLINE_X_Y: return 1;
return 2; case FORMAT_NEWLINE_X_Y:
case FORMAT_INLINE_SPRITE: return 2;
return 4; case FORMAT_INLINE_SPRITE:
default: return 4;
return 0; default:
return 0;
} }
} }
void utf8_remove_formatting(utf8* string, bool allowColours) { void utf8_remove_formatting(utf8* string, bool allowColours)
{
utf8* readPtr = string; utf8* readPtr = string;
utf8* writePtr = string; utf8* writePtr = string;
while (true) { while (true)
{
uint32_t code = utf8_get_next(readPtr, (const utf8**)&readPtr); uint32_t code = utf8_get_next(readPtr, (const utf8**)&readPtr);
if (code == 0) { if (code == 0)
{
*writePtr = 0; *writePtr = 0;
break; break;
} else if (!utf8_is_format_code(code) || (allowColours && utf8_is_colour_code(code))) { }
else if (!utf8_is_format_code(code) || (allowColours && utf8_is_colour_code(code)))
{
writePtr = utf8_write_codepoint(writePtr, code); writePtr = utf8_write_codepoint(writePtr, code);
} }
} }
@ -220,15 +263,20 @@ void utf8_remove_formatting(utf8* string, bool allowColours) {
bool utf8_is_format_code(int32_t codepoint) bool utf8_is_format_code(int32_t codepoint)
{ {
if (codepoint < 32) return true; if (codepoint < 32)
if (codepoint >= FORMAT_ARGUMENT_CODE_START && codepoint <= FORMAT_ARGUMENT_CODE_END) return true; return true;
if (codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END) return true; if (codepoint >= FORMAT_ARGUMENT_CODE_START && codepoint <= FORMAT_ARGUMENT_CODE_END)
if (codepoint == FORMAT_COMMA1DP16) return true; return true;
if (codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END)
return true;
if (codepoint == FORMAT_COMMA1DP16)
return true;
return false; return false;
} }
bool utf8_is_colour_code(int32_t codepoint) bool utf8_is_colour_code(int32_t codepoint)
{ {
if (codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END) return true; if (codepoint >= FORMAT_COLOUR_CODE_START && codepoint <= FORMAT_COLOUR_CODE_END)
return true;
return false; return false;
} }

View File

@ -7,15 +7,16 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include "User.h"
#include "../Game.h" #include "../Game.h"
#include "../ride/Ride.h" #include "../ride/Ride.h"
#include "../util/Util.h" #include "../util/Util.h"
#include "Localisation.h" #include "Localisation.h"
#include "User.h"
utf8 gUserStrings[MAX_USER_STRINGS][USER_STRING_MAX_LENGTH]; utf8 gUserStrings[MAX_USER_STRINGS][USER_STRING_MAX_LENGTH];
static bool user_string_exists(const utf8 *text); static bool user_string_exists(const utf8* text);
/** /**
* *
@ -30,19 +31,20 @@ void user_string_clear_all()
* *
* rct2: 0x006C421D * rct2: 0x006C421D
*/ */
rct_string_id user_string_allocate(int32_t base, const utf8 *text) rct_string_id user_string_allocate(int32_t base, const utf8* text)
{ {
int32_t highBits = (base & 0x7F) << 9; int32_t highBits = (base & 0x7F) << 9;
bool allowDuplicates = base & USER_STRING_DUPLICATION_PERMITTED; bool allowDuplicates = base & USER_STRING_DUPLICATION_PERMITTED;
if (!allowDuplicates && user_string_exists(text)) { if (!allowDuplicates && user_string_exists(text))
{
gGameCommandErrorText = STR_CHOSEN_NAME_IN_USE_ALREADY; gGameCommandErrorText = STR_CHOSEN_NAME_IN_USE_ALREADY;
return 0; return 0;
} }
for (int32_t i = 0; i < MAX_USER_STRINGS; i++) for (int32_t i = 0; i < MAX_USER_STRINGS; i++)
{ {
char * userString = gUserStrings[i]; char* userString = gUserStrings[i];
if (userString[0] != 0) if (userString[0] != 0)
continue; continue;
@ -67,9 +69,9 @@ void user_string_free(rct_string_id id)
gUserStrings[id][0] = 0; gUserStrings[id][0] = 0;
} }
static bool user_string_exists(const utf8 *text) static bool user_string_exists(const utf8* text)
{ {
char * userString; char* userString;
for (int32_t i = 0; i < MAX_USER_STRINGS; i++) for (int32_t i = 0; i < MAX_USER_STRINGS; i++)
{ {
userString = gUserStrings[i]; userString = gUserStrings[i];