From e704c5592b89aa31ae6a3f535bef8796af6e663b Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:11:01 +0000 Subject: [PATCH] fix text Poeverflow on Poes hint (#4598) --- .../custom-message/CustomMessageManager.cpp | 64 ++++++++++++++++++- .../custom-message/CustomMessageManager.h | 6 ++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp index 3d494b87f..2695cd3ef 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp @@ -342,6 +342,15 @@ static size_t NextLineLength(const std::string* textStr, const size_t lastNewlin nextPosJump = 1; // Assume worst case for player name 12 * 8 (widest character * longest name length) totalPixelWidth += 96; + } else if (textStr->at(currentPos) == '\x05') { + // Skip colour control characters. + nextPosJump = 2; + } else if (textStr->at(currentPos) == '\x1E') { + //For the high score char, we have to take the next Char, then use that to get a worst case scenario. + if (textStr->at(currentPos+1) == '\x01'){ + totalPixelWidth += 28; + } + nextPosJump = 2; } else { // Some characters only one byte while others are two bytes // So check both possibilities when checking for a character @@ -367,6 +376,59 @@ static size_t NextLineLength(const std::string* textStr, const size_t lastNewlin } } + +size_t CustomMessage::FindNEWLINE(std::string& str, size_t lastNewline) const { + size_t newLine = str.find(NEWLINE()[0], lastNewline); + bool done; + do { + done = true; + if (newLine != 0){ + switch (str[newLine - 1]){ + case '\x05'://COLOR + case '\x06'://SHIFT + case '\x07'://TEXTID + case '\x0C'://BOX_BREAK_DELAYED + case '\x0E'://FADE + case '\x11'://FADE2 + case '\x12'://SFX + case '\x13'://ITEM_ICON + case '\x14'://TEXT_SPEED + case '\x15'://BACKGROUND + case '\x1E'://POINTS/HIGH_SCORE + done = false; + break; + default: + break; + } + if (newLine > 1){ + switch (str[newLine - 2]){ + case '\x07'://TEXTID + case '\x11'://FADE2 + case '\x12'://SFX + case '\x15'://BACKGROUND + done = false; + break; + default: + break; + } + if (newLine > 2){ + if (str[newLine - 3] == '\x15'){//BACKGROUND + done = false; + } + } + } + } + if (!done){ + newLine = str.find(NEWLINE()[0], newLine + 1); + if (newLine != std::string::npos){ + //if we reach the end of the string, quit now to save a loop + done = true; + } + } + } while (!done); + return newLine; +} + void CustomMessage::AutoFormatString(std::string& str) const { ReplaceAltarIcons(str); ReplaceColors(str); @@ -381,7 +443,7 @@ void CustomMessage::AutoFormatString(std::string& str) const { const size_t ampersand = str.find('&', lastNewline); const size_t lastSpace = str.rfind(' ', lastNewline + lineLength); size_t waitForInput = str.find(WAIT_FOR_INPUT()[0], lastNewline); - size_t newLine = str.find(NEWLINE()[0], lastNewline); + size_t newLine = FindNEWLINE(str, lastNewline); if (carrot < waitForInput){ waitForInput = carrot; } diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.h b/soh/soh/Enhancements/custom-message/CustomMessageManager.h index 7f68f2fab..e8a969064 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.h @@ -178,6 +178,12 @@ class CustomMessage { */ void FormatString(std::string& str) const; + /** + * @brief finds NEWLINEs in a string, while filtering + * /x01's that are used as opperands + */ + size_t FindNEWLINE(std::string& str, size_t lastNewline) const; + /** * @brief formats the string specifically to fit in OoT's * textboxes, and use it's formatting.