diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index 6fa6bbbeb2..df5aad1ba2 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -17,17 +17,21 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include #include #include +#include +#include #include #include #include @@ -36,7 +40,6 @@ #include #include #include -#include enum { FILTER_RCT2 = (1 << 0), @@ -241,6 +244,8 @@ static bool filter_source(const ObjectRepositoryItem * item); static bool filter_chunks(const ObjectRepositoryItem * item); static void filter_update_counts(); +static std::string object_get_description(const void * object); + enum { RIDE_SORT_TYPE, RIDE_SORT_RIDE @@ -1057,10 +1062,10 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf gfx_draw_string_centred_clipped(dpi, STR_WINDOW_COLOUR_2_STRINGID, gCommonFormatArgs, COLOUR_BLACK, x, y, width); // Draw description of object - const char *description = object_get_description(_loadedObject); - if (description != nullptr) { + auto description = object_get_description(_loadedObject); + if (!description.empty()) { set_format_arg(0, rct_string_id, STR_STRING); - set_format_arg(2, const char *, description); + set_format_arg(2, const char *, description.c_str()); x = w->x + w->widgets[WIDX_LIST].right + 4; y += 15; @@ -1449,3 +1454,22 @@ static rct_string_id get_ride_type_string_id(const ObjectRepositoryItem * item) } return result; } + +static std::string object_get_description(const void * object) +{ + const Object * baseObject = static_cast(object); + switch (baseObject->GetObjectType()) { + case OBJECT_TYPE_RIDE: + { + const RideObject * rideObject = static_cast(baseObject); + return rideObject->GetDescription(); + } + case OBJECT_TYPE_SCENARIO_TEXT: + { + auto stexObject = static_cast(baseObject); + return stexObject->GetScenarioDetails(); + } + default: + return ""; + } +} diff --git a/src/openrct2/localisation/Language.cpp b/src/openrct2/localisation/Language.cpp index 6669720169..05a0f22365 100644 --- a/src/openrct2/localisation/Language.cpp +++ b/src/openrct2/localisation/Language.cpp @@ -239,23 +239,6 @@ bool language_get_localised_scenario_strings(const utf8 *scenarioFilename, rct_s static bool _availableObjectStringIdsInitialised = false; static std::stack _availableObjectStringIds; -rct_string_id language_allocate_object_string(const utf8 * target) -{ - if (!_availableObjectStringIdsInitialised) - { - _availableObjectStringIdsInitialised = true; - for (rct_string_id stringId = NONSTEX_BASE_STRING_ID + MAX_OBJECT_CACHED_STRINGS; stringId >= NONSTEX_BASE_STRING_ID; stringId--) - { - _availableObjectStringIds.push(stringId); - } - } - - rct_string_id stringId = _availableObjectStringIds.top(); - _availableObjectStringIds.pop(); - _languageCurrent->SetString(stringId, target); - return stringId; -} - void language_free_object_string(rct_string_id stringId) { if (stringId != 0) @@ -278,3 +261,20 @@ rct_string_id language_get_object_override_string_id(const char * identifier, ui } } + +rct_string_id language_allocate_object_string(const std::string &target) +{ + if (!_availableObjectStringIdsInitialised) + { + _availableObjectStringIdsInitialised = true; + for (rct_string_id stringId = NONSTEX_BASE_STRING_ID + MAX_OBJECT_CACHED_STRINGS; stringId >= NONSTEX_BASE_STRING_ID; stringId--) + { + _availableObjectStringIds.push(stringId); + } + } + + rct_string_id stringId = _availableObjectStringIds.top(); + _availableObjectStringIds.pop(); + _languageCurrent->SetString(stringId, target.c_str()); + return stringId; +} diff --git a/src/openrct2/localisation/language.h b/src/openrct2/localisation/language.h index 751b0680c0..b869472536 100644 --- a/src/openrct2/localisation/language.h +++ b/src/openrct2/localisation/language.h @@ -17,6 +17,10 @@ #ifndef _LANGUAGE_H_ #define _LANGUAGE_H_ +#ifdef __cplusplus +#include +#endif + #include "../common.h" #include "../drawing/font.h" @@ -115,7 +119,6 @@ utf8 *widechar_to_utf8(const wchar_t *src); utf8 *rct2_language_string_to_utf8(const char *src, size_t srcSize, RCT2LanguageId languageId); bool language_get_localised_scenario_strings(const utf8 *scenarioFilename, rct_string_id *outStringIds); -rct_string_id language_allocate_object_string(const utf8 * target); void language_free_object_string(rct_string_id stringId); rct_string_id language_get_object_override_string_id(const char * identifier, uint8 index); @@ -123,4 +126,8 @@ rct_string_id language_get_object_override_string_id(const char * identifier, ui } #endif +#ifdef __cplusplus +rct_string_id language_allocate_object_string(const std::string &target); +#endif + #endif diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index 5c01f6b917..e78bfaded3 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -35,7 +35,7 @@ Object::~Object() Memory::Free(_identifier); } -const utf8 * Object::GetOverrideString(uint8 index) const +std::string Object::GetOverrideString(uint8 index) const { const char * identifier = GetIdentifier(); rct_string_id stringId = language_get_object_override_string_id(identifier, index); @@ -45,23 +45,23 @@ const utf8 * Object::GetOverrideString(uint8 index) const { result = language_get_string(stringId); } - return result; + return String::ToStd(result); } -const utf8 * Object::GetString(uint8 index) const +std::string Object::GetString(uint8 index) const { auto sz = GetOverrideString(index); - if (sz == nullptr && index == OBJ_STRING_ID_VEHICLE_NAME) + if (sz.empty() && index == OBJ_STRING_ID_VEHICLE_NAME) { // If no vehicle name is specified, fall back to the ride name. This is also required if we fall back // to the .DAT name (which does not contain separate ride and vehicle names). return GetName(); } - else if (sz == nullptr) + else if (sz.empty()) { sz = GetStringTable()->GetString(index); } - return sz != nullptr ? sz : ""; + return sz; } rct_object_entry Object::GetScgWallsHeader() @@ -89,7 +89,7 @@ rct_object_entry Object::CreateHeader(const char name[9], uint32 flags, uint32 c #pragma GCC diagnostic ignored "-Wsuggest-final-methods" #endif -const utf8 * Object::GetName() const +std::string Object::GetName() const { return GetString(OBJ_STRING_ID_NAME); } diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index 2b0e4932d7..c193e129c7 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -65,8 +65,8 @@ protected: const StringTable * GetStringTable() const { return &_stringTable; } ImageTable * GetImageTable() { return &_imageTable; } - const utf8 * GetOverrideString(uint8 index) const; - const utf8 * GetString(uint8 index) const; + std::string GetOverrideString(uint8 index) const; + std::string GetString(uint8 index) const; public: explicit Object(const rct_object_entry &entry); @@ -84,7 +84,7 @@ public: virtual void DrawPreview(rct_drawpixelinfo * dpi, sint32 width, sint32 height) const { } virtual uint8 GetObjectType() const final { return _objectEntry.flags & 0x0F; } - virtual const utf8 * GetName() const; + virtual std::string GetName() const; virtual void SetRepositoryItem(ObjectRepositoryItem * item) const { } diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index 170683a7ac..a60ad02626 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -709,12 +709,12 @@ extern "C" Object * object = objectRepository->LoadObject(ori); if (object != nullptr) { - StexObject * stexObject = static_cast(object); - const utf8 * scenarioName = stexObject->GetScenarioName(); - const utf8 * scenarioDetails = stexObject->GetScenarioDetails(); + auto stexObject = static_cast(object); + auto scenarioName = stexObject->GetScenarioName(); + auto scenarioDetails = stexObject->GetScenarioDetails(); - String::Set(scenarioEntry->name, sizeof(scenarioEntry->name), scenarioName); - String::Set(scenarioEntry->details, sizeof(scenarioEntry->details), scenarioDetails); + String::Set(scenarioEntry->name, sizeof(scenarioEntry->name), scenarioName.c_str()); + String::Set(scenarioEntry->details, sizeof(scenarioEntry->details), scenarioDetails.c_str()); delete object; } @@ -757,39 +757,6 @@ extern "C" } } - const utf8 * object_get_description(const void * object) - { - const Object * baseObject = static_cast(object); - switch (baseObject->GetObjectType()) { - case OBJECT_TYPE_RIDE: - { - const RideObject * rideObject = static_cast(baseObject); - return rideObject->GetDescription(); - } - case OBJECT_TYPE_SCENARIO_TEXT: - { - const StexObject * stexObject = static_cast(baseObject); - return stexObject->GetScenarioDetails(); - } - default: - return ""; - } - } - - const utf8 * object_get_capacity(const void * object) - { - const Object * baseObject = static_cast(object); - switch (baseObject->GetObjectType()) { - case OBJECT_TYPE_RIDE: - { - auto rideObject = static_cast(baseObject); - return rideObject->GetCapacity(); - } - default: - return ""; - } - } - void object_draw_preview(const void * object, rct_drawpixelinfo * dpi, sint32 width, sint32 height) { const Object * baseObject = static_cast(object); diff --git a/src/openrct2/object/ObjectRepository.h b/src/openrct2/object/ObjectRepository.h index 7a87d5dd50..cfe7426170 100644 --- a/src/openrct2/object/ObjectRepository.h +++ b/src/openrct2/object/ObjectRepository.h @@ -106,8 +106,6 @@ const ObjectRepositoryItem * object_repository_find_object_by_name(const char void * object_repository_load_object(const rct_object_entry * objectEntry); void object_delete(void * object); -const utf8 * object_get_description(const void * object); -const utf8 * object_get_capacity(const void * object); void object_draw_preview(const void * object, rct_drawpixelinfo * dpi, sint32 width, sint32 height); #ifdef __cplusplus diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index eb716cb740..7c602cd389 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -328,17 +328,17 @@ void RideObject::DrawPreview(rct_drawpixelinfo * dpi, sint32 width, sint32 heigh gfx_draw_sprite(dpi, imageId, 0, 0, 0); } -const utf8 * RideObject::GetDescription() const +std::string RideObject::GetDescription() const { return GetString(OBJ_STRING_ID_DESCRIPTION); } -const utf8 * RideObject::GetCapacity() const +std::string RideObject::GetCapacity() const { return GetString(OBJ_STRING_ID_CAPACITY); } -const utf8 * RideObject::GetVehicleName() const +std::string RideObject::GetVehicleName() const { return GetString(OBJ_STRING_ID_VEHICLE_NAME); } @@ -554,4 +554,3 @@ uint8 RideObject::CalculateNumHorizontalFrames(const rct_ride_entry_vehicle * ve return numHorizontalFrames; } - diff --git a/src/openrct2/object/RideObject.h b/src/openrct2/object/RideObject.h index 34cfb4935b..f7068f65f8 100644 --- a/src/openrct2/object/RideObject.h +++ b/src/openrct2/object/RideObject.h @@ -42,9 +42,9 @@ public: void DrawPreview(rct_drawpixelinfo * dpi, sint32 width, sint32 height) const override; - const utf8 * GetDescription() const; - const utf8 * GetCapacity() const; - const utf8 * GetVehicleName() const; + std::string GetDescription() const; + std::string GetCapacity() const; + std::string GetVehicleName() const; void SetRepositoryItem(ObjectRepositoryItem * item) const override; diff --git a/src/openrct2/object/StexObject.cpp b/src/openrct2/object/StexObject.cpp index 2ee3451029..d70e1ad3d7 100644 --- a/src/openrct2/object/StexObject.cpp +++ b/src/openrct2/object/StexObject.cpp @@ -57,25 +57,22 @@ void StexObject::DrawPreview(rct_drawpixelinfo * dpi, sint32 width, sint32 heigh gfx_draw_string_centred(dpi, STR_WINDOW_NO_IMAGE, x, y, COLOUR_BLACK, nullptr); } -const utf8 * StexObject::GetName() const +std::string StexObject::GetName() const { return GetScenarioName(); } -const utf8 * StexObject::GetScenarioName() const +std::string StexObject::GetScenarioName() const { - const utf8 * name = GetStringTable()->GetString(OBJ_STRING_ID_SCENARIO_NAME); - return name != nullptr ? name : ""; + return GetStringTable()->GetString(OBJ_STRING_ID_SCENARIO_NAME); } -const utf8 * StexObject::GetScenarioDetails() const +std::string StexObject::GetScenarioDetails() const { - const utf8 * name = GetStringTable()->GetString(OBJ_STRING_ID_SCENARIO_DETAILS); - return name != nullptr ? name : ""; + return GetStringTable()->GetString(OBJ_STRING_ID_SCENARIO_DETAILS); } -const utf8 * StexObject::GetParkName() const +std::string StexObject::GetParkName() const { - const utf8 * name = GetStringTable()->GetString(OBJ_STRING_ID_PARK_NAME); - return name != nullptr ? name : ""; + return GetStringTable()->GetString(OBJ_STRING_ID_PARK_NAME); } diff --git a/src/openrct2/object/StexObject.h b/src/openrct2/object/StexObject.h index c12b1379c3..6e4aac44bd 100644 --- a/src/openrct2/object/StexObject.h +++ b/src/openrct2/object/StexObject.h @@ -38,11 +38,11 @@ public: void DrawPreview(rct_drawpixelinfo * dpi, sint32 width, sint32 height) const override; - const utf8 * GetName() const override; + std::string GetName() const override; - const utf8 * GetScenarioName() const; - const utf8 * GetScenarioDetails() const; - const utf8 * GetParkName() const; + std::string GetScenarioName() const; + std::string GetScenarioDetails() const; + std::string GetParkName() const; }; #endif diff --git a/src/openrct2/object/StringTable.cpp b/src/openrct2/object/StringTable.cpp index 3be1ca802c..d1fc9f14d4 100644 --- a/src/openrct2/object/StringTable.cpp +++ b/src/openrct2/object/StringTable.cpp @@ -40,9 +40,9 @@ static const uint8 RCT2ToOpenRCT2LanguageId[] = LANGUAGE_PORTUGUESE_BR, }; -static bool StringIsBlank(utf8 * str) +static bool StringIsBlank(const utf8 * str) { - for (utf8 * ch = str; *ch != '\0'; ch++) + for (auto ch = str; *ch != '\0'; ch++) { if (!isblank(*ch)) { @@ -52,14 +52,6 @@ static bool StringIsBlank(utf8 * str) return true; } -StringTable::~StringTable() -{ - for (auto entry : _strings) - { - Memory::Free(entry.Text); - } -} - void StringTable::Read(IReadObjectContext * context, IStream * stream, uint8 id) { try @@ -96,7 +88,7 @@ void StringTable::Read(IReadObjectContext * context, IStream * stream, uint8 id) Sort(); } -const utf8 * StringTable::GetString(uint8 id) const +std::string StringTable::GetString(uint8 id) const { for (auto &string : _strings) { @@ -108,6 +100,15 @@ const utf8 * StringTable::GetString(uint8 id) const return nullptr; } +void StringTable::SetString(uint8 id, uint8 language, const std::string &text) +{ + StringTableEntry entry; + entry.Id = id; + entry.LanguageId = language; + entry.Text = String::Duplicate(text); + _strings.push_back(entry); +} + void StringTable::Sort() { std::sort(_strings.begin(), _strings.end(), [](const StringTableEntry &a, const StringTableEntry &b) -> bool @@ -116,7 +117,7 @@ void StringTable::Sort() { if (a.LanguageId == b.LanguageId) { - return _strcmpi(a.Text, b.Text) < 0; + return String::Compare(a.Text, b.Text, true) < 0; } if (a.LanguageId == gCurrentLanguage) diff --git a/src/openrct2/object/StringTable.h b/src/openrct2/object/StringTable.h index 690575abe8..f38b5f4193 100644 --- a/src/openrct2/object/StringTable.h +++ b/src/openrct2/object/StringTable.h @@ -18,6 +18,7 @@ #ifdef __cplusplus +#include #include #include "../common.h" @@ -26,9 +27,9 @@ interface IStream; struct StringTableEntry { - uint8 Id; - uint8 LanguageId; - utf8 * Text; + uint8 Id; + uint8 LanguageId; + std::string Text; }; class StringTable @@ -37,11 +38,10 @@ private: std::vector _strings; public: - ~StringTable(); - void Read(IReadObjectContext * context, IStream * stream, uint8 id); void Sort(); - const utf8 * GetString(uint8 id) const; + std::string GetString(uint8 id) const; + void SetString(uint8 id, uint8 language, const std::string &text); }; #endif