From cfcdf3c1705e5a6330d2e8b7b3524cbf960b9ddd Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Thu, 5 Nov 2026 02:01:17 +0000 Subject: [PATCH] Decompile fn_11562 (UITextViewer::SendMsg) Batch #10538 by cremane: 0 byte-identical, 1 confirmed by peer review. - fn_11562 UITextViewer::SendMsg: logic confirmed by peer review Peer-reviewed-by: ragnarok-clanker, Yommy, KWDev, dori Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/UI/Text/UITextViewer.h | 2 +- Source/UI/Text/UITextViewerMessages.cpp | 215 ++++++++++++++---------- 2 files changed, 124 insertions(+), 93 deletions(-) diff --git a/Source/UI/Text/UITextViewer.h b/Source/UI/Text/UITextViewer.h index 629b94c0..97e20c05 100644 --- a/Source/UI/Text/UITextViewer.h +++ b/Source/UI/Text/UITextViewer.h @@ -41,7 +41,7 @@ private: bool AddNaviLinks(std::string text, unsigned addedLines); bool AddQuestLinks(std::string text, unsigned addedLines); void AddTipLinks(std::string text, unsigned addedLines); - void AppendText(char* text, int width, bool carriageReturns, bool pixels); + void AppendText(char* text, int width, int carriageReturns, int pixels); void Activate(UITextButton* button, int id); }; diff --git a/Source/UI/Text/UITextViewerMessages.cpp b/Source/UI/Text/UITextViewerMessages.cpp index 591762f3..c59fb450 100644 --- a/Source/UI/Text/UITextViewerMessages.cpp +++ b/Source/UI/Text/UITextViewerMessages.cpp @@ -24,92 +24,113 @@ #include // INLINED -void UITextViewer::Activate(UITextButton* button, int id) { - if (!button) { - return; - } - - auto& arguments = button->m_lines; - const auto number = [&](unsigned index) { return std::atoi(arguments.at(index).c_str()); }; - +__forceinline void UITextViewer::Activate(UITextButton* button, int id) { switch (id) { case 437: - if (!arguments.at(0).empty()) { - ShellExecuteA(hWnd, "open", arguments[0].c_str(), nullptr, nullptr, SW_SHOWNORMAL); + if (button) { + const std::string& url = button->GetLine(0); + + if (!url.empty()) { + ShellExecuteA(hWnd, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL); + } } break; case 438: { - if (arguments.empty()) { + if (!button) { break; } - const std::string map = arguments.at(0); - const int x = number(1); - const int y = number(2); + const int count = button->GetLinesCount(); - if (arguments.size() <= 3) { - g_navigationManager.sub_B99030(map, 2, 5, false, x, y, 1002); + if (count == 0) { break; } - const int type = number(3); - int policy = number(4); + const std::string& map = button->GetLine(0); + const int x = std::atoi(button->GetLine(1).c_str()); + const int y = std::atoi(button->GetLine(2).c_str()); - if (policy == -222) { - g_navigationManager.sub_B995D0((type == 3 ? "$$DB " : "") + map, type, 0); - break; + if (count > 3) { + const int type = std::atoi(button->GetLine(3).c_str()); + int policy = std::atoi(button->GetLine(4).c_str()); + + if (policy == -222) { + std::string name = "$$DB "; + + if (type != 3) { + name.clear(); + } + + name += map; + g_navigationManager.sub_B995D0(name, type, 0); + break; + } + + const int option = std::atoi(button->GetLine(5).c_str()); + const int target = std::atoi(button->GetLine(6).c_str()); + unsigned char flag = 0; + + if (policy >= 100) { + flag = 1; + policy -= 100; + } + + if (policy >= 10) { + flag += 2; + policy -= 10; + } + + if (policy >= 1) { + flag += 4; + } + + g_navigationManager.sub_B99030(map.c_str(), type, flag, option == 0, x, y, target); + } else { + g_navigationManager.sub_B99030(map.c_str(), 2, 5, false, x, y, 1002); } - const int option = number(5); - const int target = number(6); - unsigned char flag = 0; - - if (policy >= 100) { - flag = 1; - policy -= 100; - } - - if (policy >= 10) { - flag += 2; - policy -= 10; - } - - if (policy >= 1) { - flag += 4; - } - - g_navigationManager.sub_B99030(map, type, flag, option == 0, x, y, target); break; } case 464: { - if (arguments.empty()) { + if (!button || button->GetLinesCount() == 0) { break; } - const int idValue = !arguments.at(1).empty() ? number(1) : 0; + int idValue = 0; + + if (!button->GetLine(1).empty()) { + idValue = std::atoi(button->GetLine(1).c_str()); + } + ITEM_INFO item; item.identified = 1; item.unknown_0000[0] = static_cast(idValue); - item.unknown_0070 = 0; - item.itemId = arguments.at(0); + item.unknown_0060 = 0; + item.itemId = button->GetLine(0); - if (UIWindow* window = g_windowMgr.LookupWindow(12)) { + if (UIWindow* window = g_windowMgr.sub_A978D0(12)) { window->SendMsg(nullptr, 24, reinterpret_cast(&item), 0, 0, 0); } break; } case 517: - if (!arguments.empty()) { - if (UIWindow* window = g_windowMgr.EnsureWindow(315)) { - static_cast(window)->ShowTip(number(0)); + if (button && button->GetLinesCount() != 0) { + const std::string& tip = button->GetLine(0); + + if (UIWindow* window = g_windowMgr.sub_A978D0(315)) { + static_cast(window)->ShowTip(std::atoi(tip.c_str())); } } break; case 539: - static_cast(g_modeMgr.GetGameMode())->ReceiveServiceRequest(6, number(0)); + if (button) { + const int value = std::atoi(button->GetLine(0).c_str()); + static_cast(g_modeMgr.GetGameMode())->ReceiveServiceRequest(6, value); + } + break; default: break; @@ -117,63 +138,68 @@ void UITextViewer::Activate(UITextButton* button, int id) { } // INLINED -void UITextViewer::AppendText(char* text, int width, bool carriageReturns, bool pixels) { +__forceinline void UITextViewer::AppendText(char* text, int width, int carriageReturns, int pixels) { + const int lineWidth = width == 0 ? 35 : width; std::vector wrapped; if (width == 138) { WrapPlainText(text, wrapped, 38); - for (const auto& line : wrapped) { - this->AddLine(line.c_str()); + for (unsigned index = 0; index < wrapped.size(); ++index) { + this->AddLine(wrapped[index].c_str()); } this->unknown_00BC = (this->unknown_00BC & ~255) | 1; - this->Invalidate(); return; } - const bool linked = HasTextLinks(text); - std::string display; - - if (linked) { + if (HasTextLinks(text)) { const std::string expanded = ExpandTextEscapes(text); - std::strcpy(text, expanded.c_str()); - display = DisplayTextTag(expanded, "", ""); - display = DisplayTextTag(std::move(display), "", ""); - display = DisplayTextTag(std::move(display), "", ""); - display = DisplayTextTag(std::move(display), "", ""); - display = RemoveTextLinkInfo(std::move(display)); + strcpy_s(text, std::strlen(text) + 1, expanded.c_str()); + std::string display = DisplayUrlTextTag(text); + display = DisplayNavigationTextTag(display); + display = DisplayTipBoxTextTag(display); + display = DisplayItemTextTag(display); + display = RemoveTextLinkInfo(display); if (g_windowMgr.window_01C8) { - display = static_cast(g_windowMgr.window_01C8)->ConvertChat(std::move(display)); + display = static_cast(g_windowMgr.window_01C8)->ConvertChat(display); } std::string navigation; DisplayNavigationLink(navigation, display); - display = DisplayTextTag(std::move(navigation), "", ""); + display = DisplayQuestTextTag(navigation); + + if (pixels) { + const int scrollWidth = carriageReturns ? this->verticalBar->geometry.width + 2 : 0; + this->WrapPixelText(display.c_str(), wrapped, this->geometry.width - scrollWidth - 4); + } else { + WrapRichText(display.c_str(), wrapped, lineWidth, carriageReturns != 0); + } + + for (unsigned index = 0; index < wrapped.size(); ++index) { + this->AddLine(wrapped[index].c_str()); + } + + this->AddItemLinks(text, static_cast(wrapped.size())); + this->AddUrlLinks(text, static_cast(wrapped.size())); + this->AddNaviLinks(text, static_cast(wrapped.size())); + this->AddTipLinks(text, static_cast(wrapped.size())); + this->AddQuestLinks(text, static_cast(wrapped.size())); } else { - display = text; - } + if (pixels) { + const int scrollWidth = carriageReturns ? this->verticalBar->geometry.width + 2 : 0; + this->WrapPixelText(text, wrapped, this->geometry.width - scrollWidth - 4); + } else { + WrapRichText(text, wrapped, lineWidth, carriageReturns != 0); + } - if (pixels) { - const int scrollWidth = carriageReturns ? this->verticalBar->geometry.width + 2 : 0; - this->WrapPixelText(display.c_str(), wrapped, this->geometry.width - scrollWidth - 4); - } else { - WrapRichText(display.c_str(), wrapped, width == 0 ? 35 : width, carriageReturns); - } - - for (const auto& line : wrapped) { - this->AddLine(line.c_str()); - } - - if (linked) { - for (int kind = 0; kind < 5; ++kind) { - this->AddLinks(text, static_cast(wrapped.size()), kind); + for (unsigned index = 0; index < wrapped.size(); ++index) { + this->AddLine(wrapped[index].c_str()); } } this->unknown_00BC &= ~255; - this->Invalidate(); } // OFFSET: 0x00899E90 @@ -189,35 +215,40 @@ int UITextViewer::SendMsg(UIWindow* sender, int message, std::intptr_t argument1 const int previousX = this->horizontalOffset; UIListBox::SendMsg(sender, message, argument1, argument2, argument3, argument4); - for (UITextButton* button : this->links) { + for (unsigned index = 0; index < this->links.size(); ++index) { + UITextButton* button = this->links[index]; + if (!button) { continue; } const int row = button->m_value; - const int limit = this->topLine + this->geometry.height / this->lineHeight - this->bottomMargin; - if (row < this->topLine || row >= limit) { - button->Enable(0); - } else { + if (row >= this->topLine && row < this->geometry.height / this->lineHeight - this->bottomMargin + this->topLine) { button->Enable(1); - const int x = previousX + button->geometry.x - this->horizontalOffset; - const int y = this->lineHeight * (row - this->topLine) + 3; - button->Move(x, y); + button->Move(button->geometry.x - this->horizontalOffset + previousX, (row - this->topLine) * this->lineHeight + 3); + } else { + button->Enable(0); } } return 0; } case 18: + if (this->verticalOverflow != 0) { + this->SendMsg(this->verticalBar, 7, -1, 0, 0, 0); + } + + return 0; case 19: if (this->verticalOverflow != 0) { - this->SendMsg(this->verticalBar, 7, message == 18 ? -1 : 1, 0, 0, 0); + this->SendMsg(this->verticalBar, 7, 1, 0, 0, 0); } return 0; case 29: - this->AppendText(reinterpret_cast(argument1), static_cast(argument2), argument3 != 0, argument4 != 0); + this->AppendText(reinterpret_cast(argument1), static_cast(argument2), static_cast(argument3), static_cast(argument4)); + this->Invalidate(); return 0; case 98: this->Activate(static_cast(sender), static_cast(argument1));