From d22c6b96a67ed28af9744dd0dd352e4a4d89b032 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Tue, 27 Oct 2026 10:04:56 +0000 Subject: [PATCH] Decompile 5 functions in Source/Resource/Bitmap/BitmapImage.cpp, Source/Resource/Bitmap/BitmapImage.h, ... Batch #1026 by ragnarok-clanker: 0 byte-identical, 5 confirmed by peer review. - fn_07866 BitmapImage::CreateAuxiliary: logic confirmed by peer review - fn_07867 BitmapImage::Pixel: logic confirmed by peer review - fn_07874 BitmapImage::ClearAuxiliary: logic confirmed by peer review - fn_09684 SkinPaletteColor: logic confirmed by peer review - fn_09685 SkinPaletteChannels: logic confirmed by peer review Reviewed-by: ragnarok-clanker Adds to the build: Source/Resource/SkinPalette.cpp --- Source/Resource/Bitmap/BitmapImage.cpp | 56 ++++++++++++++++++++++++++ Source/Resource/Bitmap/BitmapImage.h | 3 ++ Source/Resource/SkinPalette.cpp | 29 +++++++++++++ Source/Resource/SkinPalette.h | 17 ++++++++ compile.json | 1 + 5 files changed, 106 insertions(+) create mode 100644 Source/Resource/SkinPalette.cpp create mode 100644 Source/Resource/SkinPalette.h diff --git a/Source/Resource/Bitmap/BitmapImage.cpp b/Source/Resource/Bitmap/BitmapImage.cpp index 841bcdf..8218c64 100644 --- a/Source/Resource/Bitmap/BitmapImage.cpp +++ b/Source/Resource/Bitmap/BitmapImage.cpp @@ -57,6 +57,62 @@ void BitmapImage::Clear() { this->auxiliary = nullptr; } +// OFFSET: 0x0074A680 +// FUNCTION: fn_07866 +bool BitmapImage::CreateAuxiliary(int mode) { + if (!this->pixels || this->auxiliary) { + return false; + } + + this->auxiliary = std::malloc(PixelBytes(this->width, this->height)); + std::memset(this->auxiliary, 255, 4u * this->width * this->height); + auto* output = static_cast(this->auxiliary); + for (int y = 0; y < this->height; ++y) { + for (int x = 0; x < this->width; ++x) { + const int index = x + y * this->width; + const std::uint32_t value = this->pixels[index]; + unsigned red = (value >> 16) & 255; + unsigned green = (value >> 8) & 255; + unsigned blue = value & 255; + if (red != 255 || blue != 255 || green != 0) { + unsigned intensity = (red + green + blue) / 3; + const unsigned minimum = mode == 1 ? 120 : 100; + if (intensity < minimum) { + intensity = minimum; + } + red = green = blue = intensity; + if (mode == 2) { + red = 200; + } else if (mode == 3) { + green = 200; + } else if (mode == 4) { + blue = 200; + } + } + output[index] = (value & 0xFF000000u) | (red << 16) | (green << 8) | blue; + } + } + return true; +} + +// OFFSET: 0x0074A7F0 +// FUNCTION: fn_07867 +std::uint32_t BitmapImage::Pixel(int x, int y) const { + if (x < 0 || x >= this->width || y < 0 || y >= this->height) { + return 0x00FF0000; + } + return this->pixels[x + y * this->width]; +} + +// OFFSET: 0x0074C540 +// FUNCTION: fn_07874 +void BitmapImage::ClearAuxiliary() { + if (this->auxiliary) { + std::free(this->auxiliary); + this->auxiliary = nullptr; + } +} + // OFFSET: 0x0074AB00 // FUNCTION: fn_07869 bool BitmapImage::DecodeBitmap(const void* input, int, bool iconOnly) { diff --git a/Source/Resource/Bitmap/BitmapImage.h b/Source/Resource/Bitmap/BitmapImage.h index cdc0dd0..358d1f4 100644 --- a/Source/Resource/Bitmap/BitmapImage.h +++ b/Source/Resource/Bitmap/BitmapImage.h @@ -14,6 +14,9 @@ struct BitmapImage { BitmapImage(); void Clear(); + bool CreateAuxiliary(int mode); + std::uint32_t Pixel(int x, int y) const; + void ClearAuxiliary(); bool DecodeBitmap(const void* data, int bytes, bool iconOnly); bool DecodeTga(const void* data, int bytes); bool DecodePng(const void* data, int bytes, const char* name); diff --git a/Source/Resource/SkinPalette.cpp b/Source/Resource/SkinPalette.cpp new file mode 100644 index 0000000..69eadfd --- /dev/null +++ b/Source/Resource/SkinPalette.cpp @@ -0,0 +1,29 @@ +#include "Resource/SkinPalette.h" +#include "Resource/Bitmap/BitmapResource.h" +#include "Resource/ResourceMgr.h" +#include "Resource/TextureNames.h" + +// OFFSET: 0x007E0F40 +// FUNCTION: fn_09684 +std::uint32_t SkinPaletteColor(ResourceMgr& resources, TextureNames& names, const SkinPaletteCell& cell, bool resolveSkin) { + const char* filename = "유저인터페이스\\colorchip.bmp"; + if (resolveSkin) { + filename = names.Resolve(filename); + } + auto* bitmap = static_cast(resources.Load(filename)); + if (!bitmap) { + return 0; + } + const std::uint32_t color = bitmap->image.Pixel(4 * cell.column + 2, 4 * cell.row + 2); + return ((color & 255) << 16) | (color & 0xFF00) | ((color >> 16) & 255); +} + +// OFFSET: 0x007E0FC0 +// FUNCTION: fn_09685 +void SkinPaletteChannels(ResourceMgr& resources, TextureNames& names, int x, int y, unsigned& red, unsigned& green, unsigned& blue) { + auto* bitmap = static_cast(resources.Load(names.Resolve("유저인터페이스\\colorchip.bmp"))); + const std::uint32_t color = bitmap->image.Pixel(x, y); + red = (color >> 16) & 255; + green = (color >> 8) & 255; + blue = color & 255; +} diff --git a/Source/Resource/SkinPalette.h b/Source/Resource/SkinPalette.h new file mode 100644 index 0000000..6fecc1a --- /dev/null +++ b/Source/Resource/SkinPalette.h @@ -0,0 +1,17 @@ +#ifndef RAGNAROK_SOURCE_RESOURCE_SKINPALETTE_H +#define RAGNAROK_SOURCE_RESOURCE_SKINPALETTE_H + +#include + +class ResourceMgr; +struct TextureNames; + +struct SkinPaletteCell { + /* 0000 */ int column; + /* 0004 */ int row; +}; + +std::uint32_t SkinPaletteColor(ResourceMgr& resources, TextureNames& names, const SkinPaletteCell& cell, bool resolveSkin); +void SkinPaletteChannels(ResourceMgr& resources, TextureNames& names, int x, int y, unsigned& red, unsigned& green, unsigned& blue); + +#endif diff --git a/compile.json b/compile.json index d5d850f..cc17e43 100644 --- a/compile.json +++ b/compile.json @@ -513,6 +513,7 @@ "Source/Resource/ResourceFailures.cpp": 3, "Source/Resource/ResourceMgr.cpp": 3, "Source/Resource/ResourceTransient.cpp": 3, + "Source/Resource/SkinPalette.cpp": 3, "Source/Resource/Sprites/ActionResource.cpp": 3, "Source/Resource/Sprites/SpriteEncoding.cpp": 3, "Source/Resource/Sprites/SpriteResource.cpp": 3,