#pragma once #include #include #include #include #include #include #include #include "common/common_types.h" #include "common/custom_data/Tfrag3Data.h" #include "common/util/FileUtil.h" namespace decompiler { struct ResolvedTextureData { u16 w; u16 h; std::vector rgba; }; struct TextureLRUCache { using Entry = std::pair; using List = std::list; using Iterator = List::iterator; size_t capacity; List entries; // front = most recently used std::unordered_map lookup; std::mutex mutex; TextureLRUCache(size_t capacity) : capacity(capacity) {} void clear() { std::lock_guard lock(mutex); entries.clear(); lookup.clear(); } ResolvedTextureData* get(u32 id) { std::lock_guard lock(mutex); auto it = lookup.find(id); if (it == lookup.end()) { return nullptr; } entries.splice(entries.begin(), entries, it->second); return &it->second->second; } void put(u32 id, ResolvedTextureData data) { std::lock_guard lock(mutex); auto it = lookup.find(id); if (it != lookup.end()) { it->second->second = std::move(data); entries.splice(entries.begin(), entries, it->second); return; } entries.emplace_front(id, std::move(data)); lookup[id] = entries.begin(); if (lookup.size() > capacity) { auto last = std::prev(entries.end()); lookup.erase(last->first); entries.pop_back(); } } }; struct TextureDB { TextureDB(); struct TextureData { u16 w, h; std::string name; u32 page; u32 dest = -1; std::vector rgba_bytes; u32 num_mips = -1; }; std::map textures; std::unordered_map tpage_names; std::unordered_map> texture_ids_per_level; std::optional merge_texture_dir; std::optional replace_texture_dir; TextureLRUCache replacement_cache; // special textures for animation. std::map index_textures_by_combo_id; std::unordered_map animated_tex_output_to_anim_slot; ResolvedTextureData resolve_texture(u32 id); static constexpr int kPlaceholderWhiteTexturePage = INT16_MAX; static constexpr int kPlaceholderWhiteTextureId = 0; void add_texture(u32 tpage, u32 texid, const std::vector& data, u16 w, u16 h, const std::string& tex_name, const std::string& tpage_name, const std::vector& level_names, u32 num_mips, u32 dest); void add_index_texture(u32 tpage, u32 texid, const std::vector& index_data, const std::array, 256>& clut, u16 w, u16 h, const std::string& tex_name, const std::string& tpage_name, const std::vector& level_names); void merge_textures(const fs::path& base_path); void replace_textures(const fs::path& path); void merge_texture(u32 id, std::vector& rgba) const; std::optional replace_texture(u32 id); std::string generate_texture_dest_adjustment_table() const; }; // used by decompiler for texture macros struct TexInfo { std::string name; std::string tpage_name; u32 idx; }; } // namespace decompiler