140 static Companion* Instance;
142 explicit Companion(std::filesystem::path rom,
const ArchiveType otr,
const bool debug,
const bool modding =
false,
143 const std::string& srcDir =
"",
const std::string& destPath =
"") : gCartridge(
nullptr),
144 gSourceDirectory(srcDir), gDestinationDirectory(destPath) {
145 this->gRomPath = rom;
146 this->gConfig.otrMode = otr;
147 this->gConfig.debug = debug;
148 this->gConfig.modding = modding;
149 this->gConfig.textureDefines =
false;
150 this->gConfig.includeAutogen =
false;
153 explicit Companion(std::vector<uint8_t> rom,
const ArchiveType otr,
const bool debug,
const bool modding =
false,
154 const std::string& srcDir =
"",
const std::string& destPath =
"") : gCartridge(
nullptr),
155 gSourceDirectory(srcDir), gDestinationDirectory(destPath) {
156 this->gRomData = rom;
157 this->gConfig.otrMode = otr;
158 this->gConfig.debug = debug;
159 this->gConfig.modding = modding;
160 this->gConfig.textureDefines =
false;
161 this->gConfig.includeAutogen =
false;
164 void SetRomPath(std::filesystem::path path) { this->gRomPath = std::move(path); }
166 explicit Companion(std::filesystem::path rom,
const ArchiveType otr,
const bool debug,
const std::string& srcDir =
"",
const std::string& destPath =
"") :
167 Companion(rom, otr, debug,
false, srcDir, destPath) {}
169 explicit Companion(std::vector<uint8_t> rom,
const ArchiveType otr,
const bool debug,
const std::string& srcDir =
"",
const std::string& destPath =
"") :
170 Companion(rom, otr, debug,
false, srcDir, destPath) {}
172 void Init(ExportType type);
173 void Init(ExportType type, std::atomic<size_t>& assetCount,
bool shouldProcess);
175 bool NodeHasChanges(
const std::string&
string);
177 void Process(std::atomic<size_t>& assetCount);
179 bool IsOTRMode()
const {
return (this->gConfig.otrMode != ArchiveType::None); }
180 bool IsDebug()
const {
return this->gConfig.debug; }
181 bool AddTextureDefines()
const {
return this->gConfig.textureDefines; }
183 N64::Cartridge* GetCartridge()
const {
return this->gCartridge.get(); }
185 const std::string& GetGameTitle()
const {
return this->gGameTitle; }
186 std::vector<uint8_t>& GetRomData() {
return this->gRomData; }
187 std::string GetOutputPath() {
return this->gConfig.outputPath; }
188 const std::string& GetAssetPath()
const {
return this->gAssetPath; }
189 std::string GetDestRelativeOutputPath() {
return RelativePathToDestDir(GetOutputPath()); }
191 GBIVersion GetGBIVersion()
const {
return this->gConfig.gbi.version; }
192 GBIMinorVersion GetGBIMinorVersion()
const {
return this->gConfig.gbi.subversion; }
193 std::unordered_map<std::string, std::vector<YAML::Node>> GetCourseMetadata() {
return this->gCourseMetadata; }
194 std::optional<std::string> GetEnumFromValue(
const std::string& key,
int id);
195 bool IsUsingIndividualIncludes()
const {
return this->gIndividualIncludes; }
197 std::optional<ParseResultData> GetParseDataByAddr(uint32_t addr);
198 std::optional<ParseResultData> GetParseDataBySymbol(
const std::string& symbol);
200 std::optional<std::uint32_t> GetFileOffsetFromSegmentedAddr(uint8_t segment)
const;
201 std::optional<std::pair<std::uint32_t, std::uint32_t>> GetFileOffsetFromCompressedSegmentedAddr(uint8_t segment)
const;
202 std::optional<std::shared_ptr<BaseFactory>> GetFactory(
const std::string& type);
203 uint32_t PatchVirtualAddr(uint32_t addr);
205 std::optional<std::tuple<std::string, YAML::Node>> GetNodeByAddr(uint32_t addr);
208 std::optional<std::tuple<std::string, YAML::Node>> GetNodeByAddr(uint32_t addr,
const std::string& file);
209 std::optional<std::string> GetStringByAddr(uint32_t addr);
210 std::optional<std::tuple<std::string, YAML::Node>> GetSafeNodeByAddr(
const uint32_t addr, std::string type);
211 std::optional<std::string> GetSafeStringByAddr(
const uint32_t addr, std::string type);
212 std::optional<std::vector<std::tuple<std::string, YAML::Node>>> GetNodesByType(
const std::string& type,
bool includeAutogen =
false);
217 const std::vector<std::tuple<std::string, YAML::Node>>* GetNodesByTypeRef(
const std::string& type,
bool includeAutogen =
false);
218 std::string GetSymbolFromAddr(uint32_t addr,
bool validZero =
false);
220 std::string GetCurrentFile(
void) {
return this->gCurrentFile; }
221 std::optional<std::uint32_t> GetFileOffsetFromName(
void)
const {
return this->gCurrentFileOffset; };
222 std::uint32_t GetCurrSegmentNumber(
void)
const {
return this->gCurrentSegmentNumber; };
223 CompressionType GetCurrCompressionType(
void)
const {
return this->gCurrentCompressionType; };
224 std::optional<std::uint32_t> GetCurrentCompressedSize(
void)
const {
return this->gCurrentCompressedSize; };
225 std::optional<VRAMEntry> GetCurrentVRAM(
void)
const {
return this->gCurrentVram; };
226 std::optional<Table> SearchTable(uint32_t addr);
228 static std::vector<char> ParseVersionString(
const std::string& version);
229 static std::string CalculateHash(
const std::vector<uint8_t>& data);
230 static void Pack(
const std::string& folder,
const std::string& output,
const ArchiveType otrMode,
const std::string& version =
"");
231 std::string NormalizeAsset(
const std::string& name)
const;
232 std::string RelativePath(
const std::string& path)
const;
233 std::string RelativePathToSrcDir(
const std::string& path)
const;
234 std::string RelativePathToDestDir(
const std::string& path)
const;
235 void RegisterCompanionFile(
const std::string path, std::vector<char> data);
236 void RegisterArchiveFile(
const std::string& name, std::vector<char> data);
237 void SetAdditionalFiles(
const std::vector<std::string>& files) { this->gAdditionalFiles = files; }
238 void SetVersion(
const std::string& version) { this->gVersion = version; }
240 std::string GetCurrentAssetName()
const {
return this->gCurrentAssetName; }
241 void SetAssetTotal(std::atomic<size_t>* total) { this->gAssetTotal = total; }
242 void SetPhaseCallback(std::function<
void(
int)> cb) { this->gPhaseCallback = cb; }
244 void SetProcess(
bool shouldProcess);
246 const YAML::Node& GetCurrentFileConfig()
const {
return this->gCurrentFileConfig; }
247 const std::string& GetCurrentModdingSource()
const {
return this->gCurrentModdingSource; }
248 BinaryWrapper* GetCurrentWrapper() {
return this->gCurrentWrapper; }
249 const std::unordered_map<std::string, std::string>& GetModdedAssetPaths()
const {
return this->gModdedAssetPaths; }
251 std::optional<std::tuple<std::string, YAML::Node>> RegisterAsset(
const std::string& name, YAML::Node& node);
252 std::optional<YAML::Node> AddSubFileAsset(YAML::Node asset, std::string newFileName, CompressionType newCompressionType, uint32_t compressedSize = 0);
253 std::optional<YAML::Node> AddAsset(YAML::Node asset);
254 std::string GetCurrentDirectory()
const {
return gCurrentDirectory.generic_string(); }
255 void SetCompressedSegment(uint32_t segmentId, uint32_t compressedFileOffset, uint32_t offset);
256 bool GetCompressedSegmentOffset(uint32_t* addr);
258 void SetSingleYMLPath(
const std::string& path) { this->gSingleYMLPath = path; }
259 uint32_t GetFileOffsetFromName(
const std::string& file)
const {
return this->gFileOffsets.at(file); }
262 void RegisterUIFactory(
const std::string& type,
const std::shared_ptr<BaseFactoryUI>& factory);
263 std::optional<std::shared_ptr<BaseFactoryUI>> GetUIFactory(
const std::string& type);
264 const std::unordered_map<std::string, std::vector<ParseResultData>>& GetParseResults() {
return this->gParseResults; }
268 YAML::Node gModdingConfig;
269 YAML::Node gCurrentFileConfig;
270 std::string gCurrentModdingSource;
271 fs::path gSourceDirectory;
272 fs::path gDestinationDirectory;
273 fs::path gCurrentDirectory;
274 std::string gCurrentHash;
275 std::string gAssetPath;
276 std::string gCommonAssetPath;
277 std::string gVersion;
278 std::string gSingleYMLPath;
279 std::vector<uint8_t> gRomData;
280 std::optional<std::filesystem::path> gRomPath;
281 bool gNodeForceProcessing =
false;
282 bool gIndividualIncludes =
false;
283 YAML::Node gHashNode;
284 std::shared_ptr<N64::Cartridge> gCartridge;
285 std::string gGameTitle;
286 std::unordered_map<std::string, std::vector<YAML::Node>> gCourseMetadata;
287 std::unordered_map<std::string, std::unordered_map<int32_t, std::string>> gEnums;
291 std::string gCurrentAssetName;
292 std::atomic<size_t>* gAssetCounter =
nullptr;
293 std::atomic<size_t>* gAssetTotal =
nullptr;
294 std::function<void(
int)> gPhaseCallback;
295 std::string gCurrentFile;
296 std::vector<std::string> gSubFileList;
297 std::string gCurrentVirtualPath;
298 std::string gFileHeader;
299 bool gEnablePadGen =
false;
300 bool mShouldProcess =
true;
301 uint32_t gCurrentPad = 0;
302 uint32_t gCurrentFileOffset;
303 uint32_t gCurrentSegmentNumber;
304 std::optional<VRAMEntry> gCurrentVram;
305 CompressionType gCurrentCompressionType = CompressionType::None;
306 std::optional<std::uint32_t> gCurrentCompressedSize;
307 std::vector<Table> gTables;
308 std::vector<std::string> gCurrentExternalFiles;
309 std::unordered_map<int, std::string> gManualSegments;
310 std::unordered_set<std::string> gProcessedFiles;
311 std::unordered_map<std::string, uint32_t> gFileOffsets;
313 std::unordered_map<std::string, std::vector<char>> gCompanionFiles;
314 std::vector<std::pair<std::string, std::vector<char>>> gArchiveFiles;
315 std::unordered_map<std::string, std::vector<ParseResultData>> gParseResults;
316 std::vector<std::string> gAdditionalFiles;
318 std::unordered_map<std::string, std::string> gModdedAssetPaths;
319 std::variant<std::vector<std::string>, std::string> gWriteOrder;
320 std::unordered_map<std::string, std::shared_ptr<BaseFactory>> gFactories;
322 std::unordered_map<std::string, std::shared_ptr<BaseFactoryUI>> gUIFactories;
324 std::unordered_map<std::string, std::map<std::string, std::vector<WriteEntry>>> gWriteMap;
325 std::unordered_map<std::string, std::tuple<uint32_t, uint32_t>> gVirtualAddrMap;
326 std::unordered_map<std::string, std::unordered_map<uint32_t, std::tuple<std::string, YAML::Node>>> gAddrMap;
330 std::unordered_map<std::string,
331 std::unordered_map<std::string, std::array<std::vector<std::tuple<std::string, YAML::Node>>, 2>>>
334 std::unordered_map<std::string, std::unordered_map<std::string, uint8_t>> gNodesByTypeCacheValid;
336 void ProcessParseFile(YAML::Node root, std::atomic<size_t>& assetCount);
337 void ProcessExportFile();
338 void ProcessFile(YAML::Node root);
339 void ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount);
340 std::optional<std::tuple<std::string, YAML::Node>> FindNodeInOverlaySegments(uint32_t addr,
const std::string& file);
341 std::optional<std::tuple<std::string, YAML::Node>> FindInExternalByVRAM(uint32_t addr,
const std::string& file);
342 void ParseEnums(std::string& file);
344 void ParseModdingConfig();
345 void ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& assetCount);
346 void RegisterFactory(
const std::string& type,
const std::shared_ptr<BaseFactory>& factory);
347 void ExtractNode(YAML::Node& node, std::string& name,
BinaryWrapper* binary);
348 void ProcessTables(YAML::Node& rom);
349 void LoadYAMLRecursively(
const std::string &dirPath, std::vector<YAML::Node> &result,
bool skipRoot);
350 std::vector<fs::directory_entry> GetAssetYMLs(YAML::Node& rom)
const;
351 std::optional<ParseResultData> ParseNode(YAML::Node& node, std::string& name);
352 void ParseFilelist(
const std::string& filelistPath);
353 void SetSegmentInfo(
const YAML::Node& segments);
354 uint32_t GetFileOffsetFromNodeStr(
const std::string& str)
const;