From dcecaa8a094b986bf960519e4bb13c22ea70a741 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Wed, 28 Oct 2026 12:16:43 +0000 Subject: [PATCH] Decompile 5 functions in Source/UI/WindowTitlebar.cpp, Source/UI/WindowBackground.cpp, ... Batch #1396 by Yommy: 0 byte-identical, 5 confirmed by peer review. - fn_12098 UIWindow::DrawTitleBar: logic confirmed by peer review - fn_12099 UIWindow::DrawTitleBarAt: logic confirmed by peer review - fn_12085 UIWindow::DrawPanelBackground: logic confirmed by peer review - fn_12086 UIWindow::DrawPanelBackgroundAt: logic confirmed by peer review - fn_12088 UIWindow::DrawButtonBar: logic confirmed by peer review Reviewed-by: ragnarok-clanker Adds to the build: Source/UI/WindowTitlebar.cpp, Source/UI/WindowBackground.cpp --- Source/UI/Window/UIWindow.h | 6 ++ Source/UI/Window/WindowBorder.cpp | 74 ++++++++++++++++++++++++ Source/UI/WindowBackground.cpp | 64 +++++++++++++++++++++ Source/UI/WindowTitlebar.cpp | 95 +++++++++++++++++++++++++++++++ data/compile.json | 2 + 5 files changed, 241 insertions(+) create mode 100644 Source/UI/WindowBackground.cpp create mode 100644 Source/UI/WindowTitlebar.cpp diff --git a/Source/UI/Window/UIWindow.h b/Source/UI/Window/UIWindow.h index d85a91b..6df3190 100644 --- a/Source/UI/Window/UIWindow.h +++ b/Source/UI/Window/UIWindow.h @@ -21,6 +21,7 @@ struct RenderQueues; struct BitmapImage; class FontCache; struct TextLocale; +struct TextureNames; struct tagRECT; struct tagSIZE; struct ActionFrame; @@ -141,6 +142,11 @@ public: int FormattedTextWidth(FontCache& fonts, const TextLocale& locale, std::string text, int family, int height, unsigned char bold); int RestoreEditTexts(const unsigned char* data); bool FitSprite(const ActionFrame* frame, const CSprRes* sprite, int width, int height, int* x, int* y, float* scale); + int DrawTitleBar(TextureNames& names, FontCache& fonts, const TextLocale& locale, bool closeButton, const char* title, int width); + int DrawTitleBarAt(TextureNames& names, FontCache& fonts, const TextLocale& locale, int x, int width, bool closeButton, const char* title); + void DrawPanelBackground(TextureNames& names, int y, int width, const char* bitmapName); + void DrawPanelBackgroundAt(TextureNames& names, int x, int y, int width, const char* bitmapName); + int DrawButtonBar(TextureNames& names, int style, int width, int rows); // INLINED bool HasTextBackground() const { diff --git a/Source/UI/Window/WindowBorder.cpp b/Source/UI/Window/WindowBorder.cpp index 4892160..3cf5485 100644 --- a/Source/UI/Window/WindowBorder.cpp +++ b/Source/UI/Window/WindowBorder.cpp @@ -1,8 +1,12 @@ #include "Render/DeviceContext/DeviceContext.h" +#include "Resource/Bitmap/BitmapResource.h" +#include "Resource/ResourceMgr.h" +#include "Resource/TextureNames.h" #include "UI/Window/UIWindow.h" #include "UI/Window/WindowBorder.h" #include +#include namespace {} @@ -70,3 +74,73 @@ void FillTriangle(UIWindow& window, int x0, int y0, int x1, int y1, int x2, int window.geometry.surface->ReleaseDC(dc); } } + +// OFFSET: 0x008D0920 +// FUNCTION: fn_12088 +int UIWindow::DrawButtonBar(TextureNames& names, int style, int width, int rows) { + if (width == 0) { + width = this->geometry.width; + } + + int leftWidth = 0; + int rightWidth = 0; + int barHeight = 0; + char buffer[260]; + const char* name; + + if (style) { + std::sprintf(buffer, "유저인터페이스\\basic_interface\\btnbar_left%d.bmp", style); + name = buffer; + } else { + name = "유저인터페이스\\basic_interface\\btnbar_left.bmp"; + } + + auto* left = static_cast(ResourceMgr::Instance().Load(names.Resolve(name))); + if (left) { + leftWidth = left->image.width; + barHeight = left->image.height; + + for (int row = 1; row <= rows; ++row) { + this->DrawBitmap(0, this->geometry.height - row * barHeight, &left->image, false); + } + } + + if (style) { + std::sprintf(buffer, "유저인터페이스\\basic_interface\\btnbar_right%d.bmp", style); + name = buffer; + } else { + name = "유저인터페이스\\basic_interface\\btnbar_right.bmp"; + } + + auto* right = static_cast(ResourceMgr::Instance().Load(names.Resolve(name))); + if (right) { + rightWidth = right->image.width; + + for (int row = 1; row <= rows; ++row) { + this->DrawBitmap(width - rightWidth, this->geometry.height - row * barHeight, &right->image, false); + } + } + + if (style) { + std::sprintf(buffer, "유저인터페이스\\basic_interface\\btnbar_mid%d.bmp", style); + name = buffer; + } else { + name = "유저인터페이스\\basic_interface\\btnbar_mid.bmp"; + } + + auto* middle = static_cast(ResourceMgr::Instance().Load(names.Resolve(name))); + if (!middle) { + return 0; + } + + const int extent = width - rightWidth - leftWidth; + const int count = extent / middle->image.width + (extent % middle->image.width != 0); + + for (int row = 1; row <= rows; ++row) { + for (int column = 0; column < count; ++column) { + this->DrawBitmap(leftWidth + column * middle->image.width, this->geometry.height - row * barHeight, &middle->image, false); + } + } + + return middle->image.height; +} diff --git a/Source/UI/WindowBackground.cpp b/Source/UI/WindowBackground.cpp new file mode 100644 index 0000000..7e957bd --- /dev/null +++ b/Source/UI/WindowBackground.cpp @@ -0,0 +1,64 @@ +#include "Resource/Bitmap/BitmapResource.h" +#include "Resource/ResourceMgr.h" +#include "Resource/SkinPalette.h" +#include "Resource/TextureNames.h" +#include "UI/Window/UIWindow.h" +#include "UI/Window/WindowBorder.h" + +#include +#include + +// OFFSET: 0x008D03E0 +// FUNCTION: fn_12085 +void UIWindow::DrawPanelBackground(TextureNames& names, int y, int width, const char* bitmapName) { + if (std::strlen(bitmapName) != 0) { + auto* bitmap = static_cast(ResourceMgr::Instance().Load(names.Resolve(bitmapName))); + if (bitmap) { + this->DrawBitmap(0, y, &bitmap->image, false); + } + return; + } + + if (width == 0) { + width = this->geometry.width; + } + + unsigned red; + unsigned green; + unsigned blue; + SkinPaletteChannels(ResourceMgr::Instance(), names, 14, 6, red, green, blue); + DrawRoundedBorder(*this, 0, y, width, this->geometry.height - y, RGB(red, green, blue)); + this->FillRegion(0, y, width, 5, RGB(red, green, blue)); + + SkinPaletteChannels(ResourceMgr::Instance(), names, 2, 2, red, green, blue); + this->FillRegion(1, y, width - 2, this->geometry.height - y - 2, RGB(red, green, blue)); + this->FillRegion(2, this->geometry.height - 2, width - 4, 1, RGB(red, green, blue)); +} + +// OFFSET: 0x008D0530 +// FUNCTION: fn_12086 +void UIWindow::DrawPanelBackgroundAt(TextureNames& names, int x, int y, int width, const char* bitmapName) { + if (bitmapName && std::strlen(bitmapName) != 0) { + auto* bitmap = static_cast(ResourceMgr::Instance().Load(names.Resolve(bitmapName))); + if (bitmap) { + this->DrawBitmap(x, y, &bitmap->image, false); + } + return; + } + + if (width == 0) { + width = this->geometry.width - x; + } + + const int height = this->geometry.height; + unsigned red; + unsigned green; + unsigned blue; + SkinPaletteChannels(ResourceMgr::Instance(), names, 14, 6, red, green, blue); + DrawRoundedBorder(*this, x, y, width, height - y, RGB(red, green, blue)); + this->FillRegion(x, y, width, 5, RGB(red, green, blue)); + + SkinPaletteChannels(ResourceMgr::Instance(), names, 2, 2, red, green, blue); + this->FillRegion(x + 1, y, width - 2, height - y - 2, RGB(red, green, blue)); + this->FillRegion(x + 2, height - 2, width - 4, 1, RGB(red, green, blue)); +} diff --git a/Source/UI/WindowTitlebar.cpp b/Source/UI/WindowTitlebar.cpp new file mode 100644 index 0000000..b740c0c --- /dev/null +++ b/Source/UI/WindowTitlebar.cpp @@ -0,0 +1,95 @@ +#include "Resource/Bitmap/BitmapResource.h" +#include "Resource/ResourceMgr.h" +#include "Resource/TextureNames.h" +#include "UI/Window/UIWindow.h" + +// OFFSET: 0x008D2CE0 +// FUNCTION: fn_12098 +int UIWindow::DrawTitleBar(TextureNames& names, FontCache& fonts, const TextLocale& locale, bool closeButton, const char* title, int width) { + if (width == 0) { + width = this->geometry.width; + } + + int left = 0; + int titleHeight = 0; + auto* leftBar = static_cast(ResourceMgr::Instance().Load(names.Resolve("유저인터페이스\\basic_interface\\titlebar_left.bmp"))); + if (leftBar) { + this->DrawBitmap(0, 0, &leftBar->image, false); + left = leftBar->image.width; + } + + int right = 0; + auto* rightBar = static_cast(ResourceMgr::Instance().Load(names.Resolve("유저인터페이스\\basic_interface\\titlebar_right.bmp"))); + if (rightBar) { + right = rightBar->image.width; + this->DrawBitmap(width - right, 0, &rightBar->image, false); + } + + auto* middle = static_cast(ResourceMgr::Instance().Load(names.Resolve("유저인터페이스\\basic_interface\\titlebar_mid.bmp"))); + if (middle) { + titleHeight = middle->image.height; + const int extent = width - right - left; + const int count = extent / middle->image.width + (extent % middle->image.width != 0); + + for (int index = 0; index < count; ++index) { + this->DrawBitmap(left, 0, &middle->image, false); + left += middle->image.width; + } + } + + this->DrawTextAt(fonts, locale, 19, titleHeight - 13, title, 0, 0, 12, 0xFFFFFF, 0, 0); + this->DrawTextAt(fonts, locale, 18, titleHeight - 14, title, 0, 0, 12, 0, 0, 0); + + if (closeButton) { + auto* icon = static_cast(ResourceMgr::Instance().Load(names.Resolve("유저인터페이스\\basic_interface\\sys_base_off.bmp"))); + this->DrawBitmap(3, 3, icon ? &icon->image : nullptr, true); + } + + return titleHeight; +} + +// OFFSET: 0x008D2E50 +// FUNCTION: fn_12099 +int UIWindow::DrawTitleBarAt(TextureNames& names, FontCache& fonts, const TextLocale& locale, int x, int width, bool closeButton, const char* title) { + if (width <= 0) { + width = this->geometry.width - x; + } + + int left = 0; + int right = 0; + int titleHeight = 0; + auto* leftBar = static_cast(ResourceMgr::Instance().Load(names.Resolve("유저인터페이스\\basic_interface\\titlebar_left.bmp"))); + if (leftBar) { + this->DrawBitmap(x, 0, &leftBar->image, false); + left = leftBar->image.width; + } + + auto* rightBar = static_cast(ResourceMgr::Instance().Load(names.Resolve("유저인터페이스\\basic_interface\\titlebar_right.bmp"))); + if (rightBar) { + right = rightBar->image.width; + this->DrawBitmap(x - right + width, 0, &rightBar->image, false); + } + + auto* middle = static_cast(ResourceMgr::Instance().Load(names.Resolve("유저인터페이스\\basic_interface\\titlebar_mid.bmp"))); + if (middle) { + titleHeight = middle->image.height; + const int extent = width - right - left; + const int count = extent / middle->image.width + (extent % middle->image.width != 0); + + for (int index = 0; index < count; ++index) { + this->DrawBitmap(x + left + index * middle->image.width, 0, &middle->image, false); + } + } + + this->DrawTextAt(fonts, locale, x + 19, titleHeight - 13, title, 0, 0, 12, 0xFFFFFF, 0, 0); + this->DrawTextAt(fonts, locale, x + 18, titleHeight - 14, title, 0, 0, 12, 0, 0, 0); + + if (closeButton) { + auto* icon = static_cast(ResourceMgr::Instance().Load(names.Resolve("유저인터페이스\\basic_interface\\sys_base_off.bmp"))); + if (icon) { + this->DrawBitmap(x + 3, 3, &icon->image, true); + } + } + + return titleHeight; +} diff --git a/data/compile.json b/data/compile.json index 38519e2..c678a1c 100644 --- a/data/compile.json +++ b/data/compile.json @@ -628,6 +628,8 @@ "Source/UI/Window/WindowPolicy.cpp": 2, "Source/UI/Window/WindowRegistration.cpp": 2, "Source/UI/Window/WindowRetirement.cpp": 2, + "Source/UI/WindowBackground.cpp": 2, + "Source/UI/WindowTitlebar.cpp": 2, "Source/Utility/AES.cpp": 0, "Source/Utility/Async/AsyncDiagnostic.cpp": 0, "Source/Utility/Async/NAsyncWork.cpp": 0,