neptools

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

gbnl.hpp (4047B)


      1 #ifndef UUID_9037C300_D4EF_473C_8387_A1A9797069A7
      2 #define UUID_9037C300_D4EF_473C_8387_A1A9797069A7
      3 #pragma once
      4 
      5 #include "../dumpable.hpp"
      6 #include "../endian.hpp"
      7 #include "../source.hpp"
      8 #include "../dynamic_struct.hpp"
      9 #include "../txt_serializable.hpp"
     10 
     11 #include <libshit/lua/auto_table.hpp>
     12 
     13 #include <boost/endian/arithmetic.hpp>
     14 
     15 #include <optional>
     16 #include <vector>
     17 
     18 namespace Neptools
     19 {
     20 
     21   class Gbnl : public Dumpable, public TxtSerializable
     22   {
     23     LIBSHIT_DYNAMIC_OBJECT;
     24   public:
     25     struct Header // or Footer
     26     {
     27       char magic[3];
     28       char endian;
     29 
     30       std::uint16_t field_04;
     31       std::uint16_t field_06;
     32       std::uint32_t field_08;
     33       std::uint32_t field_0c;
     34       std::uint32_t flags; // 1 if there's a string, 0 otherwise?
     35       std::uint32_t descr_offset;
     36       std::uint32_t count_msgs;
     37       std::uint32_t msg_descr_size;
     38       std::uint32_t count_types;
     39       std::uint32_t offset_types;
     40       std::uint32_t field_28;
     41       std::uint32_t offset_msgs;
     42       std::uint32_t field_30;
     43       std::uint32_t field_34;
     44       std::uint32_t field_38;
     45       std::uint32_t field_3c;
     46 
     47       void Validate(std::size_t chunk_size) const;
     48     };
     49     static_assert(sizeof(Header) == 0x40);
     50 
     51     struct TypeDescriptor
     52     {
     53       enum Type
     54       {
     55         INT32  = 0,
     56         INT8   = 1,
     57         INT16  = 2,
     58         FLOAT  = 3,
     59         STRING = 5,
     60         INT64  = 6,
     61       };
     62       std::uint16_t type;
     63       std::uint16_t offset;
     64     };
     65     static_assert(sizeof(TypeDescriptor) == 0x04);
     66 
     67     struct OffsetString
     68     {
     69       std::string str;
     70       uint32_t offset;
     71     };
     72 
     73     struct FixStringTag { char str[1]; };
     74     struct PaddingTag { char pad[1]; };
     75 
     76     using Struct = DynamicStruct<
     77       int8_t, int16_t, int32_t, int64_t, float, OffsetString,
     78       FixStringTag, PaddingTag>;
     79     using StructPtr = Libshit::NotNull<boost::intrusive_ptr<Struct>>;
     80     using Messages = std::vector<StructPtr>;
     81 
     82     Gbnl(Source src);
     83     Gbnl(Endian endian, bool is_gstl, uint32_t flags, uint32_t field_28,
     84          uint32_t field_30, Libshit::AT<Struct::TypePtr> type)
     85       : endian{endian}, is_gstl{is_gstl}, flags{flags}, field_28{field_28},
     86         field_30{field_30}, type{std::move(type.Get())} {}
     87 #if LIBSHIT_WITH_LUA
     88     Gbnl(Libshit::Lua::StateRef vm, Endian endian, bool is_gstl, uint32_t flags,
     89          uint32_t field_28, uint32_t field_30, Libshit::AT<Struct::TypePtr> type,
     90          Libshit::Lua::RawTable messages);
     91 #endif
     92 
     93     void Fixup() override { RecalcSize(); }
     94 
     95     Endian endian;
     96     bool is_gstl;
     97     uint32_t flags, field_28, field_30;
     98 
     99     // no setter - it doesn't work how you expect in lua
    100     LIBSHIT_LUAGEN(get: "::Libshit::Lua::GetSmartOwnedMember")
    101     Messages messages;
    102 
    103     Struct::TypePtr type;
    104 
    105     void RecalcSize();
    106     FilePosition GetSize() const noexcept override;
    107 
    108     Libshit::NotNullSharedPtr<TxtSerializable> GetDefaultTxtSerializable(
    109       const Libshit::NotNullSharedPtr<Dumpable>& thiz) override
    110     { return Libshit::NotNullSharedPtr<TxtSerializable>{thiz.Get(), this}; }
    111 
    112   protected:
    113     // todo: private after removing GbnlItem
    114     void Dump_(Sink& sink) const override;
    115     void InspectGbnl(std::ostream& os, unsigned indent) const;
    116     void Inspect_(std::ostream& os, unsigned indent) const override;
    117 
    118   private:
    119     void WriteTxt_(std::ostream& os) const override;
    120     void ReadTxt_(std::istream& is) override;
    121 
    122     void Parse_(Source& src);
    123     void DumpHeader(Sink& sink) const;
    124     void Pad(uint16_t diff, Struct::TypeBuilder& bld, bool& int8_in_progress);
    125     FilePosition Align(FilePosition x) const noexcept;
    126 
    127     std::optional<std::int32_t> GetId(
    128       bool simple, const Gbnl::Struct& m, size_t i, size_t j, size_t& k) const;
    129     size_t FindDst(bool simple, int32_t id, std::vector<StructPtr>& messages,
    130                    size_t& index) const;
    131 
    132     size_t msg_descr_size, msgs_size;
    133     size_t real_item_count; // excluding dummy pad items
    134   };
    135 
    136   void endian_reverse_inplace(Gbnl::Header& hdr);
    137   void endian_reverse_inplace(Gbnl::TypeDescriptor& desc);
    138 }
    139 #endif