From 984681943d15301394b165b1efe68e76e072b70b Mon Sep 17 00:00:00 2001 From: lzwdgc Date: Sat, 17 Feb 2024 19:02:17 +0300 Subject: [PATCH] Initial mod_converter2. --- examples/mods/aim1_community_fix/my_mod.cpp | 2 + src/mod_converter2/mod_converter2.cpp | 146 ++++++++++++++++++++ sw.cpp | 1 + 3 files changed, 149 insertions(+) create mode 100644 src/mod_converter2/mod_converter2.cpp diff --git a/examples/mods/aim1_community_fix/my_mod.cpp b/examples/mods/aim1_community_fix/my_mod.cpp index 704a10e..a80c253 100644 --- a/examples/mods/aim1_community_fix/my_mod.cpp +++ b/examples/mods/aim1_community_fix/my_mod.cpp @@ -205,6 +205,8 @@ int main(int argc, char *argv[]) { _ADDOBJECT(EQP_ANALYZER) _ADDOBJECT(EQP_QUANTUM_TRANSLATOR) + _ADDOBJECT(EQP_INVISIBILITY_SHIELD) + _ADDOBJECT(EQP_UNIVERSAL_SHIELD) _ADDRATING(300000000) _ADDBALANCE(30000000) diff --git a/src/mod_converter2/mod_converter2.cpp b/src/mod_converter2/mod_converter2.cpp new file mode 100644 index 0000000..2db735f --- /dev/null +++ b/src/mod_converter2/mod_converter2.cpp @@ -0,0 +1,146 @@ +/* + * AIM mod_converter + * Copyright (C) 2015 lzwdgc + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "mmap.h" +#include "../model/model.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#pragma pack(push, 1) +struct mod { + using char20 = char[0x20]; + struct block { + struct header { + using texture = char20; + + BlockType type; + char20 name; + texture mask; + texture spec; + texture tex3; + texture tex4; + uint32_t all_lods; + uint32_t unk2[3]; + uint32_t unk3; + uint32_t size; + float unk4[10]; + }; + + header h; + uint32_t n_animations; + material m; + MaterialType mat_type; + }; + + int n_blocks; + char header_[0x40]; + + auto blocks() { + auto base = (uint8_t*)&header_ + sizeof(header_); + std::vector b; + auto n = n_blocks; + while (n--) { + b.push_back((block*)base); + base += sizeof(block::header) + b.back()->h.size; + } + return b; + } +}; +#pragma pack(pop) + +auto read_model(const path &fn) { + primitives::templates2::mmap_file f{fn, primitives::templates2::mmap_file::rw{}}; + auto &m = *(mod*)f.p; + auto v = m.blocks(); + for (auto &&b : v) { + if (b->h.type != BlockType::VisibleObject) { + continue; + } + switch (b->mat_type) { + case MaterialType::Texture: // works in m1 + case MaterialType::TextureWithGlareMap: // works in m1 + case MaterialType::AlphaTextureNoGlare: + case MaterialType::AlphaTextureWithOverlap: + case MaterialType::TextureWithGlareMap2: // works in m1 + case MaterialType::AlphaTextureDoubleSided: + case MaterialType::MaterialOnly: + case MaterialType::TextureWithDetalizationMap: + case MaterialType::DetalizationObjectStone: + case MaterialType::TextureWithDetalizationMapWithoutModulation: + case MaterialType::TiledTexture: + break; + case MaterialType::TextureWithGlareMapAndMask: + b->mat_type = MaterialType::TextureWithGlareMap; + break; + case MaterialType::TextureWithMask: + b->mat_type = MaterialType::Texture; + break; + default: + std::cout << b->h.name << ": " + << "warning: unknown material type " << (int)b->mat_type << " \n"; + break; + } + } +} + +void convert_model(const path &fn) +{ + read_model(fn); +} + +int main(int argc, char *argv[]) +{ + cl::opt p(cl::Positional, cl::desc(""), cl::Required); + + cl::ParseCommandLineOptions(argc, argv); + + if (fs::is_regular_file(p)) + convert_model(p); + else if (fs::is_directory(p)) + { + auto files = enumerate_files(p, false); + for (auto &f : FilesSorted(files.begin(), files.end())) + { + if (f.has_extension()) + continue; + std::cout << "processing: " << f << "\n"; + try + { + convert_model(f); + } + catch (std::exception &e) + { + std::cout << "error: " << e.what() << "\n"; + } + } + } + else + throw std::runtime_error("No such file or directory: " + to_printable_string(normalize_path(p))); + + return 0; +} diff --git a/sw.cpp b/sw.cpp index 9fba505..7179f91 100644 --- a/sw.cpp +++ b/sw.cpp @@ -59,6 +59,7 @@ void build(Solution &s) add_exe_with_common("tm_converter"); add_exe("name_generator"); add_exe_with_common("save_loader"); + add_exe_with_common("mod_converter2"); add_exe_with_common("unpaker") += "org.sw.demo.oberhumer.lzo.lzo"_dep, "org.sw.demo.xz_utils.lzma"_dep