neptools

Modding tools to Neptunia games
git clone https://git.neptards.moe/neptards/neptools.git
Log | Files | Refs | Submodules | README | LICENSE

cl3.hpp (4730B)


      1 #ifndef UUID_4CADE91E_2AF1_47AF_8425_9AA799509BFD
      2 #define UUID_4CADE91E_2AF1_47AF_8425_9AA799509BFD
      3 #pragma once
      4 
      5 #include "../endian.hpp"
      6 #include "../source.hpp"
      7 #include "../sink.hpp"
      8 
      9 #include <libshit/fixed_string.hpp>
     10 #include <libshit/container/ordered_map.hpp>
     11 #include <libshit/lua/auto_table.hpp>
     12 
     13 #include <cstdint>
     14 #include <vector>
     15 #include <boost/filesystem/path.hpp>
     16 
     17 namespace Neptools
     18 {
     19   namespace Stcm { class File; }
     20 
     21   class Cl3 final : public Libshit::RefCounted, public Dumpable
     22   {
     23     LIBSHIT_DYNAMIC_OBJECT;
     24   public:
     25     struct Header
     26     {
     27       char magic[3];
     28       char endian;
     29       std::uint32_t field_04;
     30       std::uint32_t field_08;
     31       std::uint32_t sections_count;
     32       std::uint32_t sections_offset;
     33       std::uint32_t field_14;
     34 
     35       void Validate(FilePosition file_size) const;
     36     };
     37     static_assert(sizeof(Header) == 0x18);
     38 
     39     struct Section
     40     {
     41       Libshit::FixedString<0x20> name;
     42       std::uint32_t count;
     43       std::uint32_t data_size;
     44       std::uint32_t data_offset;
     45       std::uint32_t field_2c;
     46       std::uint32_t field_30;
     47       std::uint32_t field_34;
     48       std::uint32_t field_38;
     49       std::uint32_t field_3c;
     50       std::uint32_t field_40;
     51       std::uint32_t field_44;
     52       std::uint32_t field_48;
     53       std::uint32_t field_4c;
     54 
     55       void Validate(FilePosition file_size) const;
     56     };
     57     static_assert(sizeof(Section) == 0x50);
     58 
     59     struct FileEntry
     60     {
     61       Libshit::FixedString<0x200> name;
     62       std::uint32_t field_200;
     63       std::uint32_t data_offset;
     64       std::uint32_t data_size;
     65       std::uint32_t link_start;
     66       std::uint32_t link_count;
     67       std::uint32_t field_214;
     68       std::uint32_t field_218;
     69       std::uint32_t field_21c;
     70       std::uint32_t field_220;
     71       std::uint32_t field_224;
     72       std::uint32_t field_228;
     73       std::uint32_t field_22c;
     74 
     75       void Validate(uint32_t block_size) const;
     76     };
     77     static_assert(sizeof(FileEntry) == 0x230);
     78 
     79     struct LinkEntry
     80     {
     81       std::uint32_t field_00;
     82       std::uint32_t linked_file_id;
     83       std::uint32_t link_id;
     84       std::uint32_t field_0c;
     85       std::uint32_t field_10;
     86       std::uint32_t field_14;
     87       std::uint32_t field_18;
     88       std::uint32_t field_1c;
     89 
     90       void Validate(std::uint32_t i, std::uint32_t file_count) const;
     91     };
     92     static_assert(sizeof(LinkEntry) == 0x20);
     93 
     94     struct Entry
     95       : public Libshit::OrderedMapItem, public Libshit::Lua::DynamicObject
     96     {
     97       LIBSHIT_DYNAMIC_OBJECT;
     98     public:
     99       std::string name;
    100       uint32_t field_200 = 0;
    101 
    102       using Links = std::vector<Libshit::WeakRefCountedPtr<Cl3::Entry>>;
    103       // no setter - it doesn't work how you expect in lua
    104       LIBSHIT_LUAGEN(get: "::Libshit::Lua::GetRefCountedOwnedMember")
    105       Links links;
    106 
    107       Libshit::SmartPtr<Dumpable> src;
    108 
    109       Entry(std::string name, uint32_t field_200,
    110             Libshit::SmartPtr<Dumpable> src)
    111         : name{std::move(name)}, field_200{field_200}, src{std::move(src)} {}
    112       explicit Entry(std::string name) : name{std::move(name)} {}
    113 
    114       void Dispose() noexcept override;
    115     };
    116     struct EntryKeyOfValue
    117     {
    118       using type = std::string;
    119       const type& operator()(const Entry& e) { return e.name; }
    120     };
    121     using Entries = Libshit::OrderedMap<Entry, EntryKeyOfValue>;
    122 
    123 
    124     Cl3(Source src);
    125     explicit Cl3(Endian endian = Endian::LITTLE)
    126       : endian{endian}, field_14{0} {}
    127 #if LIBSHIT_WITH_LUA
    128     Cl3(Libshit::Lua::StateRef vm, Endian endian, uint32_t field_14,
    129         Libshit::Lua::RawTable entries);
    130 #endif
    131 
    132     void Fixup() override;
    133     FilePosition GetSize() const override;
    134 
    135     Endian endian;
    136     uint32_t field_14;
    137 
    138     // no setter - it doesn't work how you expect in lua
    139     LIBSHIT_LUAGEN(get: "::Libshit::Lua::GetRefCountedOwnedMember")
    140     Entries entries;
    141     uint32_t IndexOf(const Libshit::WeakSmartPtr<Entry>& ptr) const noexcept;
    142 
    143     Entry& GetOrCreateFile(Libshit::StringView fname);
    144 
    145     void ExtractTo(const boost::filesystem::path& dir) const;
    146     void UpdateFromDir(const boost::filesystem::path& dir);
    147 
    148     Stcm::File& GetStcm();
    149 
    150     Libshit::NotNullSharedPtr<TxtSerializable> GetDefaultTxtSerializable(
    151       const Libshit::NotNullSharedPtr<Dumpable>& thiz) override;
    152 
    153     void Dispose() noexcept override;
    154 
    155   private:
    156     FilePosition data_size;
    157     unsigned link_count;
    158 
    159     void Parse_(Source& src);
    160     void Dump_(Sink& os) const override;
    161     void Inspect_(std::ostream& os, unsigned indent) const override;
    162   };
    163 
    164   void endian_reverse_inplace(Cl3::Header& hdr) noexcept;
    165   void endian_reverse_inplace(Cl3::Section& sec) noexcept;
    166   void endian_reverse_inplace(Cl3::FileEntry& entry) noexcept;
    167   void endian_reverse_inplace(Cl3::LinkEntry& entry) noexcept;
    168 }
    169 #endif