#pragma once #include "ResourceType.h" #include "n64/Cartridge.h" #include #include #include #include #include #include #include #include #include #include #include #include #define REGISTER(type, c) { ExportType::type, std::make_shared() }, #define SEGMENT_OFFSET(a) ((uint32_t)(a) & 0x00FFFFFF) #define SEGMENT_NUMBER(x) (((uint32_t)(x) >> 24) & 0xFF) // I would love to use 0x01000000, but the stupid compiler takes it as 0x01 #define IS_SEGMENTED(x) ((SEGMENT_NUMBER(x) > 0) && (SEGMENT_NUMBER(x) < 0x20)) #define ASSET_PTR(x) (IS_SEGMENTED(x) ? SEGMENT_OFFSET(x) : (x)) #define tab "\t" #define fourSpaceTab " " struct OffsetEntry { uint32_t start; uint32_t end; }; typedef std::optional> ExportResult; enum class ExportType { Header, Code, Binary, Modding }; template std::optional GetNode(YAML::Node& node, const std::string& key) { if(!node[key]) { return std::nullopt; } return std::optional(node[key].as()); } template T GetSafeNode(YAML::Node& node, const std::string& key) { if(!node[key]) { if (node["symbol"]) { throw std::runtime_error("Yaml asset missing the '" + key + "' node for '" + node["symbol"].as() + "'"); } else { throw std::runtime_error("Yaml asset missing the '" + key + "' node"); } } return node[key].as(); } template T GetSafeNode(YAML::Node& node, const std::string& key, const T& def) { if(!node[key]) { return def; } return node[key].as(); } class IParsedData{}; template class GenericData : public IParsedData { public: T mData; }; class BaseExporter { public: virtual ExportResult Export(std::ostream& write, std::shared_ptr data, std::string& entryName, YAML::Node& node, std::string* replacement) = 0; static void WriteHeader(LUS::BinaryWriter& write, LUS::ResourceType resType, int32_t version); }; class BaseFactory { public: virtual std::optional> parse(std::vector& buffer, YAML::Node& data) = 0; virtual std::optional> parse_modding(std::vector& buffer, YAML::Node& data) { return std::nullopt; } std::optional> GetExporter(ExportType type) { auto exporters = this->GetExporters(); if (exporters.find(type) != exporters.end()) { return exporters[type]; } return std::nullopt; } virtual bool SupportModdedAssets() { return false; } virtual uint32_t GetAlignment() { return 4; } virtual std::optional> CreateDataPointer() { return std::nullopt; } private: virtual std::unordered_map> GetExporters() = 0; };