From a3af37989b4d514c8c9d2606bdbfc8d30d499b4b Mon Sep 17 00:00:00 2001 From: Luminar Light <18116946+LuminarLight@users.noreply.github.com> Date: Sat, 2 Dec 2023 18:17:47 +0100 Subject: [PATCH] Allow replacing all instances of a texture with one texture (#3234) There are art groups that are present in multiple levels, and that means that also their textures are present in multiple levels. With texture replacement, currently we need to make replacements for all instances if we want it replaced everywhere, but this is not ideal, especially when you make changes to your replacement texture and now you have to put it in each folder again. I added a way to replace all instances of a texture, by letting texture-replacer people put their replacements into an '_all' folder. I set up the logic in such a way that if you have a replacement for the texture in its corresponding folder, it will take priority over a replacement that you placed into the '_all' folder. I personally found this very useful for replacing guard textures. The guards appear in a lot of levels. But ideally you want them to look the same everywhere. And that is why I looked into this and made a PR. Oh and I changed what is printed in the 'Replacing ' part because it was printing the path to our replacement, which didn't look nicely when several textures got replaced by the same replacement from the '_all' folder. So now it will print the original texture's page and name, I think this information is more useful anyway. --- decompiler/data/TextureDB.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/decompiler/data/TextureDB.cpp b/decompiler/data/TextureDB.cpp index 8cfe905a83..170bb152c1 100644 --- a/decompiler/data/TextureDB.cpp +++ b/decompiler/data/TextureDB.cpp @@ -133,20 +133,23 @@ void TextureDB::replace_textures(const fs::path& path) { fs::path base_path(path); for (auto& tex : textures) { fs::path full_path = base_path / tpage_names.at(tex.second.page) / (tex.second.name + ".png"); - if (fs::exists(full_path)) { - lg::info("Replacing {}", full_path.string().c_str()); - int w, h; - auto data = stbi_load(full_path.string().c_str(), &w, &h, 0, 4); // rgba channels - if (!data) { - lg::warn("failed to load PNG file: {}", full_path.string().c_str()); + if (!fs::exists(full_path)) { + full_path = base_path / "_all" / (tex.second.name + ".png"); + if (!fs::exists(full_path)) continue; - } - tex.second.rgba_bytes.resize(w * h); - memcpy(tex.second.rgba_bytes.data(), data, w * h * 4); - tex.second.w = w; - tex.second.h = h; - stbi_image_free(data); } + lg::info("Replacing {}", tpage_names.at(tex.second.page) + "/" + (tex.second.name)); + int w, h; + auto data = stbi_load(full_path.string().c_str(), &w, &h, 0, 4); // rgba channels + if (!data) { + lg::warn("failed to load PNG file: {}", full_path.string().c_str()); + continue; + } + tex.second.rgba_bytes.resize(w * h); + memcpy(tex.second.rgba_bytes.data(), data, w * h * 4); + tex.second.w = w; + tex.second.h = h; + stbi_image_free(data); } }