Fix importing and exporting of banner strings containing colour

This commit is contained in:
Ted John 2019-07-29 21:20:22 +01:00
parent 7287b8cf1a
commit af5daaec70
7 changed files with 63 additions and 5 deletions

View File

@ -2906,7 +2906,8 @@ private:
{
const auto originalString = _s4.string_table[(stringId - USER_STRING_START) % 1024];
std::string_view originalStringView(originalString, USER_STRING_MAX_LENGTH);
return rct2_to_utf8(originalStringView, RCT2_LANGUAGE_ID_ENGLISH_UK);
auto withoutFormatCodes = RCT12::RemoveFormatCodes(originalStringView);
return rct2_to_utf8(withoutFormatCodes, RCT2_LANGUAGE_ID_ENGLISH_UK);
}
void FixLandOwnership()

View File

@ -9,6 +9,7 @@
#include "RCT12.h"
#include "../localisation/Localisation.h"
#include "../ride/Track.h"
#include "../world/Footpath.h"
#include "../world/SmallScenery.h"
@ -413,3 +414,41 @@ bool is_user_string_id(rct_string_id stringId)
{
return stringId >= 0x8000 && stringId < 0x9000;
}
std::string RCT12::RemoveFormatCodes(const std::string_view& s)
{
constexpr auto RCT12_MULTIBYTE_PREFIX = (char)(uint8_t)0xFF;
std::string result;
result.reserve(s.size());
// Append each character that is not a format code
for (size_t i = 0; i < s.size(); i++)
{
auto c = s[i];
if (c == '\0')
{
break;
}
else if (c == RCT12_MULTIBYTE_PREFIX)
{
// Multi-byte, assume not a format code
result.push_back(c);
if (i + 1 < s.size())
{
result.push_back(s[i + 1]);
}
if (i + 2 < s.size())
{
result.push_back(s[i + 2]);
}
i += 2;
}
else if (!utf8_is_format_code(c))
{
result.push_back(c);
}
}
return result;
}

View File

@ -14,6 +14,9 @@
#include "../common.h"
#include "../world/Location.hpp"
#include <string>
#include <string_view>
#define RCT12_MAX_RIDES_IN_PARK 255
#define RCT12_MAX_AWARDS 4
#define RCT12_MAX_NEWS_ITEMS 61
@ -540,3 +543,8 @@ assert_struct_size(RCT12Banner, 8);
#pragma pack(pop)
bool is_user_string_id(rct_string_id stringId);
namespace RCT12
{
std::string RemoveFormatCodes(const std::string_view& s);
}

View File

@ -1253,7 +1253,16 @@ void S6Exporter::ExportBanner(RCT12Banner& dst, const Banner& src)
dst.flags = src.flags;
dst.string_idx = STR_DEFAULT_SIGN;
auto stringId = AllocateUserString(src.text);
auto bannerText = src.text;
if (!(src.flags & BANNER_FLAG_IS_WALL) && !(src.flags & BANNER_FLAG_IS_LARGE_SCENERY))
{
char codeBuffer[32]{};
utf8_write_codepoint(codeBuffer, FORMAT_COLOUR_CODE_START + src.text_colour);
bannerText = codeBuffer + bannerText;
}
auto stringId = AllocateUserString(bannerText);
if (stringId != opt::nullopt)
{
dst.string_idx = *stringId;

View File

@ -1524,7 +1524,8 @@ public:
{
const auto originalString = _s6.custom_strings[(stringId - USER_STRING_START) % 1024];
std::string_view originalStringView(originalString, USER_STRING_MAX_LENGTH);
return rct2_to_utf8(originalStringView, RCT2_LANGUAGE_ID_ENGLISH_UK);
auto withoutFormatCodes = RCT12::RemoveFormatCodes(originalStringView);
return rct2_to_utf8(withoutFormatCodes, RCT2_LANGUAGE_ID_ENGLISH_UK);
}
};

View File

@ -872,7 +872,7 @@ void Ride::FormatStatusTo(void* argsV) const
&& race_winner != SPRITE_INDEX_NULL)
{
auto sprite = get_sprite(race_winner);
if (sprite != nullptr)
if (sprite != nullptr && sprite->IsPeep())
{
auto peep = sprite->AsPeep();
set_format_arg_on(args, 0, rct_string_id, STR_RACE_WON_BY);

View File

@ -128,7 +128,7 @@ void tile_element_remove_banner_entry(TileElement* tileElement)
if (banner != nullptr)
{
window_close_by_number(WC_BANNER, bannerIndex);
banner = {};
*banner = {};
}
}