From 19413f28729ca5e36d806a8f05f75da1d92af86d Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Thu, 5 Nov 2026 04:01:46 +0000 Subject: [PATCH] Decompile 5 functions in Source/Resource/Sprites/SpriteEncoding.cpp, Source/Resource/Sprites/SpriteResource.cpp, ... Batch #11640 by cremane: 0 byte-identical, 5 confirmed by peer review. - fn_02405 ConvertSpritePalette: logic confirmed by peer review - fn_08062 CSprRes::ReduceSprite: logic confirmed by peer review - fn_08063 CSprRes::EncodeSpriteRuns: logic confirmed by peer review - fn_08054 CSprRes::Load: logic confirmed by peer review - fn_08055 CSprRes::Unload: logic confirmed by peer review Peer-reviewed-by: Yommy, KWDev Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Resource/Sprites/SpriteEncoding.cpp | 47 +++++++------- Source/Resource/Sprites/SpriteResource.cpp | 73 +++++++++++----------- Source/Resource/Sprites/SpriteResource.h | 4 +- 3 files changed, 61 insertions(+), 63 deletions(-) diff --git a/Source/Resource/Sprites/SpriteEncoding.cpp b/Source/Resource/Sprites/SpriteEncoding.cpp index 3107faa8..f3107f1e 100644 --- a/Source/Resource/Sprites/SpriteEncoding.cpp +++ b/Source/Resource/Sprites/SpriteEncoding.cpp @@ -4,34 +4,33 @@ // OFFSET: 0x00761070 // FUNCTION: fn_08063 -std::uint8_t* EncodeSpriteRuns(const std::uint8_t* pixels, int width, int height, std::uint16_t& bytes) { +std::uint8_t* CSprRes::EncodeSpriteRuns(const std::uint8_t* pixels, int width, int height, std::uint16_t& bytes) { std::vector encoded; - unsigned zeroCount = 0; - bool zeroRun = false; - std::uint32_t index = 0; + std::uint16_t zeroCount = 0; + int zeroRun = 0; + std::uint16_t index = 0; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x, ++index) { - const std::uint8_t pixel = pixels[static_cast(index)]; - - if (pixel == 0) { - if (!zeroRun) { + if (pixels[index] == 0) { + if (zeroRun) { + if (++zeroCount >= 255) { + encoded.push_back(static_cast(zeroCount)); + zeroRun = 0; + zeroCount = 0; + } + } else { encoded.push_back(0); - zeroRun = true; - } - - if (++zeroCount >= 255) { - encoded.push_back(static_cast(zeroCount)); - zeroRun = false; - zeroCount = 0; + zeroRun = 1; + ++zeroCount; } } else { if (zeroRun) { encoded.push_back(static_cast(zeroCount)); } - encoded.push_back(pixel); - zeroRun = false; + encoded.push_back(pixels[index]); + zeroRun = 0; zeroCount = 0; } } @@ -42,9 +41,9 @@ std::uint8_t* EncodeSpriteRuns(const std::uint8_t* pixels, int width, int height } bytes = static_cast(encoded.size()); - auto* result = static_cast(::operator new(bytes)); + auto* result = new std::uint8_t[bytes]; - for (unsigned index = 0; index < bytes; ++index) { + for (std::uint16_t index = 0; index < bytes; ++index) { result[index] = encoded[index]; } @@ -53,10 +52,10 @@ std::uint8_t* EncodeSpriteRuns(const std::uint8_t* pixels, int width, int height // OFFSET: 0x00760FE0 // FUNCTION: fn_08062 -std::uint8_t* ReduceSprite(const std::uint8_t* pixels, int width, int height, int halfWidth, int halfHeight) { +std::uint8_t* CSprRes::ReduceSprite(const std::uint8_t* pixels, int width, int height, int halfWidth, int halfHeight) { const int outputWidth = halfWidth != 0 ? width / 2 : width; const int outputHeight = halfHeight != 0 ? height / 2 : height; - auto* output = static_cast(::operator new(static_cast(outputWidth) * outputHeight)); + auto* output = new std::uint8_t[outputWidth * outputHeight]; for (int y = 0; y < outputHeight; ++y) { const auto* source = pixels + width * y * (halfHeight + 1); @@ -73,9 +72,9 @@ std::uint8_t* ReduceSprite(const std::uint8_t* pixels, int width, int height, in // FUNCTION: fn_02405 void ConvertSpritePalette(std::uint32_t* output, const std::uint8_t* input, int count) { for (int index = 0; index < count; ++index) { - const unsigned red = input[index * 4]; - const unsigned green = input[index * 4 + 1]; - const unsigned blue = input[index * 4 + 2]; + const std::uint8_t red = input[index * 4]; + const std::uint8_t green = input[index * 4 + 1]; + const std::uint8_t blue = input[index * 4 + 2]; output[index] = red >= 254 && green < 4 && blue >= 254 ? 1057u : ((blue | 0x40000u) >> 3) | (4 * ((green & 0xF8u) | (32 * (red & 0xF8u)))); } } diff --git a/Source/Resource/Sprites/SpriteResource.cpp b/Source/Resource/Sprites/SpriteResource.cpp index ad0a8bb4..53d6e4fd 100644 --- a/Source/Resource/Sprites/SpriteResource.cpp +++ b/Source/Resource/Sprites/SpriteResource.cpp @@ -32,18 +32,17 @@ CSprRes* CSprRes::Create() { bool CSprRes::Load(const char* name) { CFile file; if (!file.Open(name, 0, true, false)) { - const std::string message = std::string("Spr :: Cannot find File : ") + name; + const std::string message = std::string("Spr :: Cannot find File : ") + std::string(name); ShowErrorDialog(GetRenderSystemHolder()->system, message.c_str(), 0); return false; } - ResourceByteReader input{static_cast(file.GetData()), static_cast(file.GetSize())}; struct Header { std::uint16_t magic; std::uint16_t version; std::uint16_t indexed; } header; - input.Read(&header, sizeof(header)); + file.Read(&header, sizeof(header)); if (header.magic != 0x5053) { ShowErrorDialog(GetRenderSystemHolder()->system, "Illegal File Format", 0); @@ -60,21 +59,21 @@ bool CSprRes::Load(const char* name) { if (header.version >= 0x0101) { unsigned char colors[1024]; - input.position = input.size - sizeof(colors); - input.Read(colors, sizeof(colors)); - input.position = sizeof(header); + file.Seek(-1024, FILE_END); + file.Read(colors, sizeof(colors)); + file.Seek(sizeof(header), FILE_BEGIN); ConvertSpritePalette(this->palette, colors, 256); } std::uint16_t trueColorCount; if (header.version >= 0x0200) { - input.Read(&trueColorCount, sizeof(trueColorCount)); + file.Read(&trueColorCount, sizeof(trueColorCount)); } for (int index = 0; index < this->indexedCount; ++index) { std::uint16_t dimensions[2]; - input.Read(dimensions, sizeof(dimensions)); + file.Read(dimensions, sizeof(dimensions)); auto* image = new SpriteRleImage{}; image->width = static_cast(dimensions[0]); image->height = static_cast(dimensions[1]); @@ -83,24 +82,24 @@ bool CSprRes::Load(const char* name) { if (g_spriteHalfWidth == 0 && g_spriteHalfHeight == 0) { if (header.version < 0x0201) { const int count = image->width * image->height; - auto* pixels = static_cast(::operator new(count)); - input.Read(pixels, count); - image->runs = EncodeSpriteRuns(pixels, image->width, image->height, encodedBytes); - std::free(pixels); + auto* pixels = new std::uint8_t[count]; + file.Read(pixels, count); + image->runs = this->EncodeSpriteRuns(pixels, image->width, image->height, encodedBytes); + delete[] pixels; } else { - input.Read(&encodedBytes, sizeof(encodedBytes)); - auto* runs = static_cast(::operator new(encodedBytes)); + file.Read(&encodedBytes, sizeof(encodedBytes)); + auto* runs = new std::uint8_t[encodedBytes]; image->runs = runs; - input.Read(runs, encodedBytes); + file.Read(runs, encodedBytes); } } else { std::uint8_t* pixels; if (header.version >= 0x0201) { - input.Read(&encodedBytes, sizeof(encodedBytes)); - auto* runs = static_cast(::operator new(encodedBytes)); - input.Read(runs, encodedBytes); - pixels = static_cast(::operator new(dimensions[0] * dimensions[1])); + file.Read(&encodedBytes, sizeof(encodedBytes)); + auto* runs = new std::uint8_t[encodedBytes]; + file.Read(runs, encodedBytes); + pixels = new std::uint8_t[dimensions[0] * dimensions[1]]; const std::uint8_t* current = runs; std::uint16_t zeroCount = 0; std::uint8_t value; @@ -121,17 +120,17 @@ bool CSprRes::Load(const char* name) { } } - std::free(runs); + delete[] runs; } else { const int count = image->width * image->height; - pixels = static_cast(::operator new(count)); - input.Read(pixels, count); + pixels = new std::uint8_t[count]; + file.Read(pixels, count); } - auto* reduced = ReduceSprite(pixels, dimensions[0], dimensions[1], g_spriteHalfWidth, g_spriteHalfHeight); - std::free(pixels); - image->runs = EncodeSpriteRuns(reduced, dimensions[0] / (g_spriteHalfWidth + 1), dimensions[1] / (g_spriteHalfHeight + 1), encodedBytes); - std::free(reduced); + auto* reduced = this->ReduceSprite(pixels, dimensions[0], dimensions[1], g_spriteHalfWidth, g_spriteHalfHeight); + delete[] pixels; + image->runs = this->EncodeSpriteRuns(reduced, dimensions[0] / (g_spriteHalfWidth + 1), dimensions[1] / (g_spriteHalfHeight + 1), encodedBytes); + delete[] reduced; if (g_spriteHalfWidth != 0) { image->width /= 2; @@ -150,16 +149,16 @@ bool CSprRes::Load(const char* name) { if (header.version >= 0x0200) { for (unsigned index = 0; index < trueColorCount; ++index) { std::uint16_t dimensions[2]; - input.Read(dimensions, sizeof(dimensions)); + file.Read(dimensions, sizeof(dimensions)); auto* image = new SpriteRleImage{}; image->width = static_cast(dimensions[0]); image->height = static_cast(dimensions[1]); - auto* pixels = static_cast(::operator new(static_cast(image->width * image->height) * sizeof(std::uint32_t))); + auto* pixels = new std::uint32_t[image->width * image->height]; for (int y = image->height - 1; y >= 0; --y) { for (int x = 0; x < image->width; ++x) { std::uint8_t pixel[4]; - input.Read(pixel, sizeof(pixel)); + file.Read(pixel, sizeof(pixel)); pixels[y * image->width + x] = pixel[1] | (pixel[2] << 8) | (pixel[3] << 16) | (static_cast(pixel[0]) << 24); } } @@ -169,7 +168,7 @@ bool CSprRes::Load(const char* name) { CTexture* texture = CreateTexture(width, height, TextureFormat::A4R4G4B4, false, false); image->unknown_0008 = texture; texture->Upload(0, 0, image->width, image->height, pixels, 0, 0); - std::free(pixels); + delete[] pixels; if (g_spriteHalfWidth != 0) { image->width /= 2; @@ -192,16 +191,16 @@ bool CSprRes::Load(const char* name) { // OFFSET: 0x00760B10 // FUNCTION: fn_08055 void CSprRes::Unload() { - for (unsigned type = 0; type < 2; ++type) { - for (SpriteRleImage* image : this->images[type]) { + for (int type = 0; type < 2; ++type) { + for (auto image = this->images[type].begin(); image != this->images[type].end(); ++image) { if (type == 0) { - std::free(const_cast(image->runs)); - } else { - delete static_cast(image->unknown_0008); - image->unknown_0008 = nullptr; + delete[] (*image)->runs; + } else if ((*image)->unknown_0008) { + delete static_cast((*image)->unknown_0008); + (*image)->unknown_0008 = nullptr; } - delete image; + delete *image; } this->images[type].clear(); diff --git a/Source/Resource/Sprites/SpriteResource.h b/Source/Resource/Sprites/SpriteResource.h index 9196d6c8..20a6e916 100644 --- a/Source/Resource/Sprites/SpriteResource.h +++ b/Source/Resource/Sprites/SpriteResource.h @@ -15,6 +15,8 @@ public: CSprRes* Create() override; bool Load(const char* name) override; void Unload() override; + std::uint8_t* EncodeSpriteRuns(const std::uint8_t* pixels, int width, int height, std::uint16_t& bytes); + std::uint8_t* ReduceSprite(const std::uint8_t* pixels, int width, int height, int halfWidth, int halfHeight); /* 0110 */ std::uint32_t palette[256]; /* 0510 */ std::vector images[2]; @@ -22,8 +24,6 @@ public: }; -std::uint8_t* EncodeSpriteRuns(const std::uint8_t* pixels, int width, int height, std::uint16_t& bytes); -std::uint8_t* ReduceSprite(const std::uint8_t* pixels, int width, int height, int halfWidth, int halfHeight); void ConvertSpritePalette(std::uint32_t* output, const std::uint8_t* input, int count); #if defined(_WIN32) && !defined(_WIN64)