From 229df6d66dd16d4f824dac809f844c013275ae03 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 12 Jul 2024 22:37:00 +0200 Subject: [PATCH] Move CSStringConverter from localisation to rct12 folder (#22280) --- src/openrct2/Game.cpp | 2 +- src/openrct2/libopenrct2.vcxproj | 5 +- src/openrct2/localisation/Convert.cpp | 124 ------------------ src/openrct2/localisation/Language.h | 4 +- src/openrct2/object/StringTable.cpp | 3 +- src/openrct2/rct1/S4Importer.cpp | 2 +- .../CSStringConverter.cpp} | 117 ++++++++++++++++- .../CSStringConverter.h} | 7 + src/openrct2/rct12/RCT12.cpp | 2 +- src/openrct2/rct2/S6Importer.cpp | 1 + src/openrct2/scenario/ScenarioRepository.cpp | 3 +- test/tests/LocalisationTest.cpp | 1 + 12 files changed, 132 insertions(+), 139 deletions(-) delete mode 100644 src/openrct2/localisation/Convert.cpp rename src/openrct2/{localisation/ConversionTables.cpp => rct12/CSStringConverter.cpp} (58%) rename src/openrct2/{localisation/ConversionTables.h => rct12/CSStringConverter.h} (75%) diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index faf6cdd31b..975bdd46fd 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -38,7 +38,6 @@ #include "interface/Screenshot.h" #include "interface/Viewport.h" #include "interface/Window.h" -#include "localisation/Localisation.h" #include "management/Finance.h" #include "management/Marketing.h" #include "management/Research.h" @@ -48,6 +47,7 @@ #include "object/ObjectList.h" #include "object/WaterEntry.h" #include "platform/Platform.h" +#include "rct12/CSStringConverter.h" #include "ride/Ride.h" #include "ride/RideRatings.h" #include "ride/Station.h" diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 76a0ec26bb..6261afd5a4 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -282,7 +282,6 @@ - @@ -388,6 +387,7 @@ + @@ -811,8 +811,6 @@ - - @@ -906,6 +904,7 @@ + diff --git a/src/openrct2/localisation/Convert.cpp b/src/openrct2/localisation/Convert.cpp deleted file mode 100644 index 77c50b1853..0000000000 --- a/src/openrct2/localisation/Convert.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/***************************************************************************** - * Copyright (c) 2014-2024 OpenRCT2 developers - * - * For a complete list of all authors, please refer to contributors.md - * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 - * - * OpenRCT2 is licensed under the GNU General Public License version 3. - *****************************************************************************/ - -#include "../core/String.hpp" -#include "ConversionTables.h" -#include "Language.h" - -#include -#include - -/** - * 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 preceded with a byte value of 255. - */ -static std::wstring DecodeToWideChar(std::string_view src) -{ - std::wstring decoded; - decoded.reserve(src.size()); - for (auto it = src.begin(); it != src.end();) - { - uint8_t c = *it++; - if (c == 255) - { - // Push next two characters - uint8_t a = 0; - uint8_t b = 0; - if (it != src.end()) - { - a = *it++; - if (it != src.end()) - { - b = *it++; - } - else - { - // 2nd byte for double byte character is missing - break; - } - } - else - { - // 1st byte for double byte character is missing - break; - } - - wchar_t cp = (a << 8) | b; - decoded.push_back(cp); - } - else - { - // Push character - decoded.push_back(c); - } - } - return decoded; -} - -static std::string DecodeToMultiByte(std::string_view src) -{ - auto wide = DecodeToWideChar(src); - std::string result; - result.reserve(wide.size()); - for (auto cc : wide) - { - if (cc <= 255) - { - result.push_back(cc); - } - else - { - result.push_back((cc >> 8) & 0xFF); - result.push_back(cc & 0xFF); - } - } - return result; -} - -static int32_t GetCodePageForRCT2Language(RCT2LanguageId languageId) -{ - switch (languageId) - { - case RCT2LanguageId::Japanese: - return OpenRCT2::CodePage::CP_932; - case RCT2LanguageId::ChineseSimplified: - return OpenRCT2::CodePage::CP_936; - case RCT2LanguageId::Korean: - return OpenRCT2::CodePage::CP_949; - case RCT2LanguageId::ChineseTraditional: - return OpenRCT2::CodePage::CP_950; - default: - return OpenRCT2::CodePage::CP_1252; - } -} - -template static std::string DecodeConvertWithTable(std::string_view src, TConvertFunc func) -{ - auto decoded = DecodeToWideChar(src); - std::wstring u16; - u16.reserve(decoded.size()); - for (auto cc : decoded) - { - u16.push_back(func(cc)); - } - return String::ToUtf8(u16); -} - -std::string RCT2StringToUTF8(std::string_view src, RCT2LanguageId languageId) -{ - auto codePage = GetCodePageForRCT2Language(languageId); - if (codePage == OpenRCT2::CodePage::CP_1252) - { - // The code page used by RCT2 was not quite 1252 as some codes were used for Polish characters. - return DecodeConvertWithTable(src, EncodingConvertRCT2ToUnicode); - } - - auto decoded = DecodeToMultiByte(src); - return String::ConvertToUtf8(decoded, codePage); -} diff --git a/src/openrct2/localisation/Language.h b/src/openrct2/localisation/Language.h index b4214dd162..c679b5f95b 100644 --- a/src/openrct2/localisation/Language.h +++ b/src/openrct2/localisation/Language.h @@ -14,7 +14,6 @@ #include "../localisation/StringIdType.h" #include -#include enum { @@ -49,7 +48,7 @@ enum LANGUAGE_COUNT }; -enum class RCT2LanguageId +enum class RCT2LanguageId : uint8_t { EnglishUK, EnglishUS, @@ -89,7 +88,6 @@ uint8_t LanguageGetIDFromLocale(const char* locale); const char* LanguageGetString(StringId id); bool LanguageOpen(int32_t id); -std::string RCT2StringToUTF8(std::string_view src, RCT2LanguageId languageId); bool LanguageGetLocalisedScenarioStrings(const utf8* scenarioFilename, StringId* outStringIds); void LanguageFreeObjectString(StringId stringId); StringId LanguageAllocateObjectString(const std::string& target); diff --git a/src/openrct2/object/StringTable.cpp b/src/openrct2/object/StringTable.cpp index 6130c4b3c6..bbc3f64398 100644 --- a/src/openrct2/object/StringTable.cpp +++ b/src/openrct2/object/StringTable.cpp @@ -13,9 +13,8 @@ #include "../core/IStream.hpp" #include "../core/Json.hpp" #include "../core/String.hpp" -#include "../localisation/Language.h" -#include "../localisation/LanguagePack.h" #include "../localisation/LocalisationService.h" +#include "../rct12/CSStringConverter.h" #include "Object.h" static constexpr uint8_t RCT2ToOpenRCT2LanguageId[] = { diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index cabdb9ec21..ade14719de 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -38,7 +38,6 @@ #include "../entity/Staff.h" #include "../interface/Window.h" #include "../localisation/Date.h" -#include "../localisation/Localisation.h" #include "../management/Award.h" #include "../management/Finance.h" #include "../management/Marketing.h" @@ -49,6 +48,7 @@ #include "../object/ObjectRepository.h" #include "../peep/PeepAnimationData.h" #include "../peep/RideUseSystem.h" +#include "../rct12/CSStringConverter.h" #include "../rct12/EntryList.h" #include "../ride/RideData.h" #include "../ride/Station.h" diff --git a/src/openrct2/localisation/ConversionTables.cpp b/src/openrct2/rct12/CSStringConverter.cpp similarity index 58% rename from src/openrct2/localisation/ConversionTables.cpp rename to src/openrct2/rct12/CSStringConverter.cpp index 4643628a97..a9e7229135 100644 --- a/src/openrct2/localisation/ConversionTables.cpp +++ b/src/openrct2/rct12/CSStringConverter.cpp @@ -7,12 +7,16 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "ConversionTables.h" +#include "CSStringConverter.h" -#include "FormatCodes.h" +#include "../core/String.hpp" +#include "../localisation/FormatCodes.h" +#include "../localisation/Language.h" #include #include +#include +#include struct EncodingConvertEntry { @@ -124,3 +128,112 @@ wchar_t EncodingConvertRCT2ToUnicode(wchar_t rct2str) return rct2str; return entry->unicode; } + +/** + * 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 preceded with a byte value of 255. + */ +static std::wstring DecodeToWideChar(std::string_view src) +{ + std::wstring decoded; + decoded.reserve(src.size()); + for (auto it = src.begin(); it != src.end();) + { + uint8_t c = *it++; + if (c == 255) + { + // Push next two characters + uint8_t a = 0; + uint8_t b = 0; + if (it != src.end()) + { + a = *it++; + if (it != src.end()) + { + b = *it++; + } + else + { + // 2nd byte for double byte character is missing + break; + } + } + else + { + // 1st byte for double byte character is missing + break; + } + + wchar_t cp = (a << 8) | b; + decoded.push_back(cp); + } + else + { + // Push character + decoded.push_back(c); + } + } + return decoded; +} + +static std::string DecodeToMultiByte(std::string_view src) +{ + auto wide = DecodeToWideChar(src); + std::string result; + result.reserve(wide.size()); + for (auto cc : wide) + { + if (cc <= 255) + { + result.push_back(cc); + } + else + { + result.push_back((cc >> 8) & 0xFF); + result.push_back(cc & 0xFF); + } + } + return result; +} + +static int32_t GetCodePageForRCT2Language(RCT2LanguageId languageId) +{ + switch (languageId) + { + case RCT2LanguageId::Japanese: + return OpenRCT2::CodePage::CP_932; + case RCT2LanguageId::ChineseSimplified: + return OpenRCT2::CodePage::CP_936; + case RCT2LanguageId::Korean: + return OpenRCT2::CodePage::CP_949; + case RCT2LanguageId::ChineseTraditional: + return OpenRCT2::CodePage::CP_950; + default: + return OpenRCT2::CodePage::CP_1252; + } +} + +template static std::string DecodeConvertWithTable(std::string_view src, TConvertFunc func) +{ + auto decoded = DecodeToWideChar(src); + std::wstring u16; + u16.reserve(decoded.size()); + for (auto cc : decoded) + { + u16.push_back(func(cc)); + } + return String::ToUtf8(u16); +} + +std::string RCT2StringToUTF8(std::string_view src, RCT2LanguageId languageId) +{ + auto codePage = GetCodePageForRCT2Language(languageId); + if (codePage == OpenRCT2::CodePage::CP_1252) + { + // The code page used by RCT2 was not quite 1252 as some codes were used for Polish characters. + return DecodeConvertWithTable(src, EncodingConvertRCT2ToUnicode); + } + + auto decoded = DecodeToMultiByte(src); + return String::ConvertToUtf8(decoded, codePage); +} diff --git a/src/openrct2/localisation/ConversionTables.h b/src/openrct2/rct12/CSStringConverter.h similarity index 75% rename from src/openrct2/localisation/ConversionTables.h rename to src/openrct2/rct12/CSStringConverter.h index ce2e7538b2..e301a8be20 100644 --- a/src/openrct2/localisation/ConversionTables.h +++ b/src/openrct2/rct12/CSStringConverter.h @@ -9,4 +9,11 @@ #pragma once +#include +#include + +enum class RCT2LanguageId : uint8_t; + wchar_t EncodingConvertRCT2ToUnicode(wchar_t rct2str); + +std::string RCT2StringToUTF8(std::string_view src, RCT2LanguageId languageId); diff --git a/src/openrct2/rct12/RCT12.cpp b/src/openrct2/rct12/RCT12.cpp index 3af6d4b165..da95ad54be 100644 --- a/src/openrct2/rct12/RCT12.cpp +++ b/src/openrct2/rct12/RCT12.cpp @@ -11,9 +11,9 @@ #include "../core/String.hpp" #include "../localisation/Formatting.h" -#include "../localisation/Localisation.h" #include "../object/ObjectList.h" #include "../rct1/Tables.h" +#include "../rct12/CSStringConverter.h" #include "../rct2/RCT2.h" #include "../ride/Ride.h" #include "../ride/Track.h" diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 7b00114641..ce39a4a8dd 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -50,6 +50,7 @@ #include "../object/ObjectRepository.h" #include "../object/WallSceneryEntry.h" #include "../peep/RideUseSystem.h" +#include "../rct12/CSStringConverter.h" #include "../rct12/EntryList.h" #include "../rct12/RCT12.h" #include "../rct12/SawyerChunkReader.h" diff --git a/src/openrct2/scenario/ScenarioRepository.cpp b/src/openrct2/scenario/ScenarioRepository.cpp index 63388f7eb4..d593b40191 100644 --- a/src/openrct2/scenario/ScenarioRepository.cpp +++ b/src/openrct2/scenario/ScenarioRepository.cpp @@ -23,10 +23,9 @@ #include "../core/Numerics.hpp" #include "../core/Path.hpp" #include "../core/String.hpp" -#include "../localisation/Language.h" -#include "../localisation/Localisation.h" #include "../localisation/LocalisationService.h" #include "../platform/Platform.h" +#include "../rct12/CSStringConverter.h" #include "../rct12/RCT12.h" #include "../rct12/SawyerChunkReader.h" #include "../rct2/RCT2.h" diff --git a/test/tests/LocalisationTest.cpp b/test/tests/LocalisationTest.cpp index 04a0859183..920e6377ab 100644 --- a/test/tests/LocalisationTest.cpp +++ b/test/tests/LocalisationTest.cpp @@ -9,6 +9,7 @@ #include "helpers/StringHelpers.hpp" #include "openrct2/localisation/Language.h" +#include "openrct2/rct12/CSStringConverter.h" #include