#pragma once #include #include #include #include #include #include #include #include "factories/BaseFactory.h" #include "n64/Cartridge.h" #include "utils/Decompressor.h" class SWrapper; namespace fs = std::filesystem; enum class GBIVersion { f3d, f3dex, f3db, f3dex2, f3dexb, }; enum class GBIMinorVersion { None, Mk64, SM64 }; enum class TableMode { Reference, Append }; struct SegmentConfig { std::unordered_map global; std::unordered_map local; std::unordered_map temporal; }; struct Table { std::string name; uint32_t start; uint32_t end; TableMode mode; }; struct VRAMEntry { uint32_t addr; uint32_t offset; }; struct WriteEntry { uint32_t addr; uint32_t alignment; std::string buffer; std::optional endptr; }; struct GBIConfig { GBIVersion version = GBIVersion::f3d; GBIMinorVersion subversion = GBIMinorVersion::None; }; struct TorchConfig { GBIConfig gbi; SegmentConfig segment; std::string outputPath; std::string moddingPath; ExportType exporterType; bool otrMode; bool debug; bool modding; }; class Companion { public: static Companion* Instance; explicit Companion(std::filesystem::path rom, const bool otr, const bool debug, const bool modding = false) : gRomPath(std::move(rom)), gCartridge(nullptr) { this->gConfig.otrMode = otr; this->gConfig.debug = debug; this->gConfig.modding = modding; } void Init(ExportType type); void PrepareCache(const std::string& string); void Process(); bool IsOTRMode() const { return this->gConfig.otrMode; } bool IsDebug() const { return this->gConfig.debug; } N64::Cartridge* GetCartridge() const { return this->gCartridge.get(); } std::vector GetRomData() { return this->gRomData; } std::string GetOutputPath() { return this->gConfig.outputPath; } GBIVersion GetGBIVersion() const { return this->gConfig.gbi.version; } GBIMinorVersion GetGBIMinorVersion() const { return this->gConfig.gbi.subversion; } std::optional GetEnumFromValue(const std::string& key, int id); std::optional GetFileOffsetFromSegmentedAddr(uint8_t segment) const; std::optional> GetNodeByAddr(uint32_t addr); std::optional> GetFactory(const std::string& type); std::optional>> GetNodesByType(const std::string& type); std::optional GetFileOffset(void) const { return this->gCurrentFileOffset; }; std::optional GetCurrSegmentNumber(void) const { return this->gCurrentSegmentNumber; }; CompressionType GetCurrCompressionType(void) const { return this->gCurrentCompressionType; }; CompressionType GetCompressionType(std::vector& buffer, const uint32_t offset); std::optional GetCurrentVRAM(void) const { return this->gCurrentVram; }; std::optional SearchTable(uint32_t addr); static std::string CalculateHash(const std::vector& data); static void Pack(const std::string& folder, const std::string& output); std::string NormalizeAsset(const std::string& name) const; TorchConfig& GetConfig() { return this->gConfig; } std::optional> RegisterAsset(const std::string& name, YAML::Node& node); std::optional AddAsset(YAML::Node asset); private: TorchConfig gConfig; YAML::Node gModdingConfig; fs::path gCurrentDirectory; std::string gCurrentCacheHash; std::vector gRomData; std::filesystem::path gRomPath; bool gNodeIsCacheable; std::shared_ptr gCartridge; std::unordered_map> gEnums; // Temporal Variables std::string gCurrentFile; std::string gFileHeader; bool gEnablePadGen = false; uint32_t gCurrentPad = 0; uint32_t gCurrentFileOffset; uint32_t gCurrentSegmentNumber; std::optional gCurrentVram; CompressionType gCurrentCompressionType = CompressionType::None; std::vector
gTables; std::variant, std::string> gWriteOrder; std::unordered_map> gFactories; std::unordered_map gModdedAssetPaths; std::unordered_map> gCacheData; std::unordered_map>> gWriteMap; std::unordered_map>> gAssetDependencies; std::unordered_map>> gAddrMap; void ParseEnums(std::string& file); void ParseModdingConfig(); void ParseCurrentFileConfig(YAML::Node node); void RegisterFactory(const std::string& type, const std::shared_ptr& factory); void StoreCache(const std::vector& value); void ExtractNode(YAML::Node& node, std::string& name, SWrapper* binary); };