rodecomp/Source/Render/Textures/TextureCache.cpp
ragnarok-clanker e168b4e4a6 Restore translation-unit ownership and publish verified source corrections
Owner-authorized source migration: 31 helper-only translation units were merged into their callers or existing inline headers; both build manifests updated. Includes the preserved source payload, Lua configuration matching wowdecomp, and exact malloca expansion without diagnostic pragmas.

449 native units compiled locally and 449 staged units compiled by the pinned server toolchain. No previously byte-matched function regressed. Compiler mapping diagnostics remain recorded as needs_cleanup, not accepted or peer-confirmed. Existing independent review records are preserved. README.md is intentionally unchanged.
2026-10-25 15:42:21 +00:00

154 lines
4.5 KiB
C++

#include "Render/RenderSystemBase.h"
#include "Render/Textures/Texture.h"
#include "Render/Textures/TextureCache.h"
#include "Resource/Bitmap/BitmapResource.h"
#include "Resource/ResourceMgr.h"
#include <cstring>
#include <windows.h>
#include <timeapi.h>
// INLINED
bool TextureNameLess::operator()(const char* left, const char* right) const {
return std::strcmp(left, right) < 0;
}
// OFFSET: 0x004074F5
// FUNCTION: fn_00152
TextureCache::TextureCache(ResourceMgr& resources, CRenderSystemBase*& system, TextureSources& sources, const int& reduction, const unsigned& reuseDelay)
: m_resources(resources), m_system(system), m_sources(sources), m_reduction(reduction), m_reuseDelay(reuseDelay) {
}
// OFFSET: 0x005713C0
// FUNCTION: fn_02447
TextureCache::~TextureCache() {
this->Clear();
}
// OFFSET: 0x00571790
// FUNCTION: fn_02453
CTexture* TextureCache::Default() {
return this->m_system ? this->m_system->BackBufferTexture() : nullptr;
}
// OFFSET: 0x005715E0
// FUNCTION: fn_02449
CTexture* TextureCache::Upload(int width, int height, const std::uint32_t* pixels, int format, int option, bool fullSize, bool dynamic, bool renderTarget) {
const int outputWidth = fullSize ? width : width / this->m_reduction;
const int outputHeight = fullSize ? height : height / this->m_reduction;
CTexture* texture = this->m_system ? this->m_system->CreateTexture(outputWidth, outputHeight, format, dynamic, renderTarget) : nullptr;
if (texture) {
texture->Upload(0, 0, width, height, pixels, option, 0);
texture->unknown_0008 = (texture->unknown_0008 & 0xFF00u) | fullSize;
}
return texture;
}
// OFFSET: 0x00571930
// FUNCTION: fn_02455
CTexture* TextureCache::Create(const char* name, int option, bool fullSize, bool dynamic, bool renderTarget) {
if (std::strstr(name, ".bik")) {
int width;
int height;
if (this->m_sources.MovieSize(name, width, height)) {
CTexture* texture = this->m_system ? this->m_system->CreateTexture(width, height, TextureFormat::A8R8G8B8, false, false) : nullptr;
if (texture) {
return texture;
}
}
} else {
auto* bitmap = static_cast<CBitmapRes*>(this->m_resources.Load(this->m_sources.Resolve(name)));
if (bitmap) {
const auto& image = bitmap->image;
CTexture* texture = this->Upload(
image.width, image.height, image.pixels, image.alpha != 0 ? TextureFormat::A4R4G4B4 : TextureFormat::A1R5G5B5, option, fullSize, dynamic, renderTarget
);
this->m_resources.Remove(bitmap);
return texture;
}
}
const int extent = 1 / this->m_reduction;
CTexture* texture = this->m_system ? this->m_system->CreateTexture(extent, extent, TextureFormat::A1R5G5B5, false, false) : nullptr;
if (texture) {
const std::uint32_t transparent = 0;
texture->Upload(0, 0, 1, 1, &transparent, option, 0);
texture->unknown_0008 &= 0xFF00u;
}
return texture;
}
// OFFSET: 0x005717A0
// FUNCTION: fn_02454
CTexture* TextureCache::Load(const char* name, int option, bool fullSize, bool dynamic, bool renderTarget) {
const auto found = this->m_textures.find(name);
if (found != this->m_textures.end() && found->second) {
found->second->unknown_0020 = timeGetTime();
return found->second;
}
CTexture* texture = this->Create(name, option, fullSize, dynamic, renderTarget);
if (!texture) {
return this->Default();
}
strncpy_s(texture->m_name, sizeof(texture->m_name), name, _TRUNCATE);
texture->unknown_0020 = timeGetTime();
this->m_textures.emplace(texture->m_name, texture);
return texture;
}
// OFFSET: 0x005716F0
// FUNCTION: fn_02452
void TextureCache::Remove(CTexture* texture) {
if (texture->unknown_001C == 0 && texture != this->Default()) {
const auto found = this->m_textures.find(texture->m_name);
if (found != this->m_textures.end()) {
delete found->second;
this->m_textures.erase(found);
}
}
}
// OFFSET: 0x00571670
// FUNCTION: fn_02451
void TextureCache::Clear() {
for (auto& [name, texture] : this->m_textures) {
delete texture;
}
this->m_textures.clear();
}
// OFFSET: 0x00571C50
// FUNCTION: fn_02457
void TextureCache::ClearUnused() {
const unsigned threshold = timeGetTime() - this->m_reuseDelay;
for (auto entry = this->m_textures.begin(); entry != this->m_textures.end();) {
CTexture* texture = entry->second;
if (texture->unknown_001C != 0 || texture->unknown_0020 >= threshold) {
++entry;
} else {
delete texture;
entry = this->m_textures.erase(entry);
}
}
HeapCompact(GetProcessHeap(), 0);
this->m_sources.CleanupTextures();
}