diff --git a/contributors.md b/contributors.md index a7dfe0ed66..2e45dc504d 100644 --- a/contributors.md +++ b/contributors.md @@ -247,6 +247,7 @@ Appreciation for contributors who have provided substantial work, but are no lon * Robert Yan (lewyche) * Tom Matalenas (tmatale) * Brendan Heinonen (staticinvocation) +* (QuestionableDeer) ## Toolchain * (Balletie) - macOS diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 697c3df739..6d06a68865 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,6 +1,7 @@ 0.4.20 (in development) ------------------------------------------------------------------------ - Improved: [#23677] Building new ride track now inherits the colour scheme from the previous piece. +- Fix: [#9999, #10000, #10001, #10002, #10003] Truncated scenario strings when using Catalan, Czech, Japanese, Polish or Russian. - Fix: [#21768] Dirty blocks debug overlay is rendered incorrectly on high DPI screens. - Fix: [#22617] Sloped Wooden and Side-Friction supports draw out of order when built directly above diagonal track pieces. - Fix: [#23522] Diagonal sloped Steeplechase supports have glitched sprites at the base. diff --git a/src/openrct2-ui/windows/ScenarioSelect.cpp b/src/openrct2-ui/windows/ScenarioSelect.cpp index ef5e7e4003..6c45024ab6 100644 --- a/src/openrct2-ui/windows/ScenarioSelect.cpp +++ b/src/openrct2-ui/windows/ScenarioSelect.cpp @@ -239,7 +239,7 @@ namespace OpenRCT2::Ui::Windows + ScreenCoordsXY{ widgets[WIDX_SCENARIOLIST].right + 4, widgets[WIDX_TABCONTENT].top + 5 }; auto ft = Formatter(); ft.Add(STR_STRING); - ft.Add(scenario->Name); + ft.Add(scenario->Name.c_str()); DrawTextEllipsised( dpi, screenPos + ScreenCoordsXY{ 85, 0 }, 170, STR_WINDOW_COLOUR_2_STRINGID, ft, { TextAlignment::CENTRE }); screenPos.y += 15; @@ -247,7 +247,7 @@ namespace OpenRCT2::Ui::Windows // Scenario details ft = Formatter(); ft.Add(STR_STRING); - ft.Add(scenario->Details); + ft.Add(scenario->Details.c_str()); screenPos.y += DrawTextWrapped(dpi, screenPos, 170, STR_BLACK_STRING, ft) + 5; // Scenario objective @@ -445,13 +445,11 @@ namespace OpenRCT2::Ui::Windows bool isDisabled = listItem.scenario.is_locked; // Draw scenario name - char buffer[64]; - String::safeUtf8Copy(buffer, scenario->Name, sizeof(buffer)); StringId format = isDisabled ? static_cast(STR_STRINGID) : (isHighlighted ? highlighted_format : unhighlighted_format); auto ft = Formatter(); ft.Add(STR_STRING); - ft.Add(buffer); + ft.Add(scenario->Name.c_str()); auto colour = isDisabled ? colours[1].withFlag(ColourFlag::inset, true) : ColourWithFlags{ COLOUR_BLACK }; auto darkness = isDisabled ? TextDarkness::Dark : TextDarkness::Regular; diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index 5ee0502be2..863281231d 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -215,15 +215,15 @@ namespace OpenRCT2 std::string name; ReadWriteStringTable(cs, name, "en-GB"); - String::set(entry.Name, sizeof(entry.Name), name.c_str()); - String::set(entry.InternalName, sizeof(entry.InternalName), name.c_str()); + entry.Name = name; + entry.InternalName = name; std::string parkName; ReadWriteStringTable(cs, parkName, "en-GB"); std::string scenarioDetails; ReadWriteStringTable(cs, scenarioDetails, "en-GB"); - String::set(entry.Details, sizeof(entry.Details), scenarioDetails.c_str()); + entry.Details = scenarioDetails; entry.ObjectiveType = cs.Read(); entry.ObjectiveArg1 = cs.Read(); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index fcceed6923..1719032c5b 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -262,7 +262,7 @@ namespace OpenRCT2::RCT1 desc.title = name.c_str(); } - String::set(dst->InternalName, sizeof(dst->InternalName), desc.title); + dst->InternalName = desc.title; if (!desc.textObjectId.empty()) { @@ -284,8 +284,8 @@ namespace OpenRCT2::RCT1 } } - String::set(dst->Name, sizeof(dst->Name), name.c_str()); - String::set(dst->Details, sizeof(dst->Details), details.c_str()); + dst->Name = name; + dst->Details = details; return true; } diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 332e5cad32..c06086cb4e 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -257,18 +257,17 @@ namespace OpenRCT2::RCT2 if (String::isNullOrEmpty(_s6.Info.Name)) { // If the scenario doesn't have a name, set it to the filename - String::set(dst->Name, sizeof(dst->Name), Path::GetFileNameWithoutExtension(dst->Path).c_str()); + dst->Name = Path::GetFileNameWithoutExtension(dst->Path); } else { // Normalise the name to make the scenario as recognisable as possible. - auto normalisedName = ScenarioSources::NormaliseName(_s6.Info.Name); - String::set(dst->Name, sizeof(dst->Name), normalisedName.c_str()); + dst->Name = ScenarioSources::NormaliseName(_s6.Info.Name); } // Look up and store information regarding the origins of this scenario. SourceDescriptor desc; - if (ScenarioSources::TryGetByName(dst->Name, &desc)) + if (ScenarioSources::TryGetByName(dst->Name.c_str(), &desc)) { dst->ScenarioId = desc.id; dst->SourceIndex = desc.index; @@ -290,8 +289,8 @@ namespace OpenRCT2::RCT2 } // dst->name will be translated later so keep the untranslated name here - String::set(dst->InternalName, sizeof(dst->InternalName), dst->Name); - String::set(dst->Details, sizeof(dst->Details), _s6.Info.Details); + dst->InternalName = dst->Name; + dst->Details = _s6.Info.Details; if (!desc.textObjectId.empty()) { @@ -308,11 +307,8 @@ namespace OpenRCT2::RCT2 if (auto* obj = objManager.LoadObject(desc.textObjectId); obj != nullptr) { auto* textObject = reinterpret_cast(obj); - auto name = textObject->GetScenarioName(); - auto details = textObject->GetScenarioDetails(); - - String::set(dst->Name, sizeof(dst->Name), name.c_str()); - String::set(dst->Details, sizeof(dst->Details), details.c_str()); + dst->Name = textObject->GetScenarioName(); + dst->Details = textObject->GetScenarioDetails(); } } diff --git a/src/openrct2/scenario/ScenarioRepository.cpp b/src/openrct2/scenario/ScenarioRepository.cpp index 6420759ea9..87fa8af2b6 100644 --- a/src/openrct2/scenario/ScenarioRepository.cpp +++ b/src/openrct2/scenario/ScenarioRepository.cpp @@ -71,10 +71,10 @@ static int32_t ScenarioIndexEntryCompareByCategory(const ScenarioIndexEntry& ent { return static_cast(entryA.SourceGame) - static_cast(entryB.SourceGame); } - return strcmp(entryA.Name, entryB.Name); + return strcmp(entryA.Name.c_str(), entryB.Name.c_str()); case SCENARIO_CATEGORY_REAL: case SCENARIO_CATEGORY_OTHER: - return strcmp(entryA.Name, entryB.Name); + return strcmp(entryA.Name.c_str(), entryB.Name.c_str()); } } @@ -317,7 +317,7 @@ public: return nullptr; } - const ScenarioIndexEntry* GetByInternalName(const utf8* name) const override + const ScenarioIndexEntry* GetByInternalName(u8string_view name) const override { for (size_t i = 0; i < _scenarios.size(); i++) { diff --git a/src/openrct2/scenario/ScenarioRepository.h b/src/openrct2/scenario/ScenarioRepository.h index dbe2966050..8099349477 100644 --- a/src/openrct2/scenario/ScenarioRepository.h +++ b/src/openrct2/scenario/ScenarioRepository.h @@ -58,9 +58,9 @@ struct ScenarioIndexEntry int16_t ObjectiveArg3; ScenarioHighscoreEntry* Highscore = nullptr; - utf8 InternalName[64]; // Untranslated name - utf8 Name[64]; // Translated name - utf8 Details[256]; + u8string InternalName; // Untranslated name + u8string Name; // Translated name + u8string Details; }; namespace OpenRCT2 @@ -83,7 +83,7 @@ struct IScenarioRepository /** * Does not return custom scenarios due to the fact that they may have the same name. */ - virtual const ScenarioIndexEntry* GetByInternalName(const utf8* name) const = 0; + virtual const ScenarioIndexEntry* GetByInternalName(u8string_view name) const = 0; virtual const ScenarioIndexEntry* GetByPath(const utf8* path) const = 0; virtual bool TryRecordHighscore(int32_t language, const utf8* scenarioFileName, money64 companyValue, const utf8* name) = 0; diff --git a/src/openrct2/scenario/ScenarioSources.cpp b/src/openrct2/scenario/ScenarioSources.cpp index 8b24eba611..69b5658c4a 100644 --- a/src/openrct2/scenario/ScenarioSources.cpp +++ b/src/openrct2/scenario/ScenarioSources.cpp @@ -357,7 +357,7 @@ namespace OpenRCT2::ScenarioSources #pragma endregion - bool TryGetByName(const utf8* name, SourceDescriptor* outDesc) + bool TryGetByName(u8string_view name, SourceDescriptor* outDesc) { Guard::ArgumentNotNull(outDesc, GUARD_LINE); diff --git a/src/openrct2/scenario/ScenarioSources.h b/src/openrct2/scenario/ScenarioSources.h index dec700be8c..460bee36bd 100644 --- a/src/openrct2/scenario/ScenarioSources.h +++ b/src/openrct2/scenario/ScenarioSources.h @@ -23,7 +23,7 @@ struct SourceDescriptor namespace OpenRCT2::ScenarioSources { - bool TryGetByName(const utf8* name, SourceDescriptor* outDesc); + bool TryGetByName(u8string_view name, SourceDescriptor* outDesc); bool TryGetById(uint8_t id, SourceDescriptor* outDesc); u8string NormaliseName(u8string_view input); } // namespace OpenRCT2::ScenarioSources