diff --git a/src/openrct2-ui/windows/Changelog.cpp b/src/openrct2-ui/windows/Changelog.cpp index 696f41627f..2624113cca 100644 --- a/src/openrct2-ui/windows/Changelog.cpp +++ b/src/openrct2-ui/windows/Changelog.cpp @@ -14,16 +14,17 @@ *****************************************************************************/ #pragma endregion +#include +#include #include #include #include -#include -#include - -#include +#include #include #include #include +#include +#include enum { WIDX_BACKGROUND, @@ -89,10 +90,8 @@ static rct_window_event_list window_changelog_events = { static bool window_changelog_read_file(); static void window_changelog_dispose_file(); -static char *_changelogText = nullptr; -static size_t _changelogTextSize = 0; -static char **_changelogLines = nullptr; -static sint32 _changelogNumLines = 0; +static std::string _changelogText; +static std::vector _changelogLines; static sint32 _changelogLongestLineWidth = 0; rct_window * window_changelog_open() @@ -164,7 +163,7 @@ static void window_changelog_resize(rct_window *w) static void window_changelog_scrollgetsize(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height) { *width = _changelogLongestLineWidth + 4; - *height = _changelogNumLines * 11; + *height = (sint32)(_changelogLines.size() * 11); } static void window_changelog_invalidate(rct_window *w) @@ -192,73 +191,76 @@ static void window_changelog_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 x = 3; sint32 y = 3; - for (sint32 i = 0; i < _changelogNumLines; i++) { - gfx_draw_string(dpi, _changelogLines[i], w->colours[0], x, y); + for (auto line : _changelogLines) + { + gfx_draw_string(dpi, (char *)line, w->colours[0], x, y); y += 11; } } -static bool window_changelog_read_file() +static std::string GetChangelogText() { - window_changelog_dispose_file(); utf8 path[MAX_PATH]; platform_get_changelog_path(path, sizeof(path)); - if (!readentirefile(path, (void**)&_changelogText, &_changelogTextSize)) { + +#if defined(_WIN32) && !defined(__MINGW32__) + auto pathW = String::ToUtf16(path); + auto fs = std::ifstream(pathW, std::ios::out | std::ios::app); +#else + auto fs = std::ifstream(path, std::ios::out | std::ios::app); +#endif + return std::string((std::istreambuf_iterator(fs)), std::istreambuf_iterator()); +} + +static bool window_changelog_read_file() +{ + try + { + _changelogText = GetChangelogText(); + } + catch (const std::bad_alloc &) + { + log_error("Unable to allocate memory for changelog.txt"); + return false; + } + catch (const std::exception &) + { log_error("Unable to read changelog.txt"); return false; } - void* new_memory = realloc(_changelogText, _changelogTextSize + 1); - if (new_memory == nullptr) { - log_error("Failed to reallocate memory for changelog text"); - return false; - } - _changelogText = (char*)new_memory; - _changelogText[_changelogTextSize++] = 0; - char *start = _changelogText; - if (_changelogTextSize >= 3 && utf8_is_bom(_changelogText)) + auto * start = _changelogText.data(); + if (_changelogText.size() >= 3 && utf8_is_bom(start)) + { start += 3; + } - sint32 changelogLinesCapacity = 8; - _changelogLines = Memory::Allocate(changelogLinesCapacity * sizeof(char*)); - _changelogLines[0] = start; - _changelogNumLines = 1; - - char *ch = start; - while (*ch != 0) { + _changelogLines.clear(); + _changelogLines.push_back(start); + auto ch = start; + while (*ch != '\0') + { uint8 c = *ch; - if (c == '\n') { + if (c == '\n') + { *ch++ = 0; - _changelogNumLines++; - if (_changelogNumLines > changelogLinesCapacity) { - changelogLinesCapacity *= 2; - new_memory = realloc(_changelogLines, changelogLinesCapacity * sizeof(char*)); - if (new_memory == nullptr) { - log_error("Failed to reallocate memory for change log lines"); - return false; - } - _changelogLines = (char**)new_memory; - } - _changelogLines[_changelogNumLines - 1] = ch; - } else if (c < 32 || c > 122) { - // A character that won't be drawn or change state. + _changelogLines.push_back(ch); + } + else if (utf8_is_format_code(c)) + { *ch++ = FORMAT_OUTLINE_OFF; - } else { + } + else + { ch++; } } - new_memory = realloc(_changelogLines, _changelogNumLines * sizeof(char*)); - if (new_memory == nullptr) { - log_error("Failed to reallocate memory for change log lines"); - return false; - } - _changelogLines = (char**)new_memory; - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; _changelogLongestLineWidth = 0; - for (sint32 i = 0; i < _changelogNumLines; i++) { - sint32 width = gfx_get_string_width(_changelogLines[i]); + for (auto line : _changelogLines) + { + auto width = gfx_get_string_width(line); _changelogLongestLineWidth = Math::Max(width, _changelogLongestLineWidth); } return true; @@ -266,8 +268,7 @@ static bool window_changelog_read_file() static void window_changelog_dispose_file() { - SafeFree(_changelogText); - SafeFree(_changelogLines); - _changelogTextSize = 0; - _changelogNumLines = 0; + _changelogText = std::string(); + _changelogLines.clear(); + _changelogLines.shrink_to_fit(); }