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::optional<std::uint32_t> GetFileOffset(
void)
const {
return this->gCurrentFileOffset; };
221 std::optional<std::uint32_t> GetCurrSegmentNumber(
void)
const {
return this->gCurrentSegmentNumber; };
222 CompressionType GetCurrCompressionType(
void)
const {
return this->gCurrentCompressionType; };
223 std::optional<std::uint32_t> GetCurrentCompressedSize(
void)
const {
return this->gCurrentCompressedSize; };
224 std::optional<VRAMEntry> GetCurrentVRAM(
void)
const {
return this->gCurrentVram; };
225 std::optional<Table> SearchTable(uint32_t addr);
227 static std::vector<char> ParseVersionString(
const std::string& version);
228 static std::string CalculateHash(
const std::vector<uint8_t>& data);
229 static void Pack(
const std::string& folder,
const std::string& output,
const ArchiveType otrMode,
const std::string& version =
"");
230 std::string NormalizeAsset(
const std::string& name)
const;
231 std::string RelativePath(
const std::string& path)
const;
232 std::string RelativePathToSrcDir(
const std::string& path)
const;
233 std::string RelativePathToDestDir(
const std::string& path)
const;
234 void RegisterCompanionFile(
const std::string path, std::vector<char> data);
235 void RegisterArchiveFile(
const std::string& name, std::vector<char> data);
236 void SetAdditionalFiles(
const std::vector<std::string>& files) { this->gAdditionalFiles = files; }
237 void SetVersion(
const std::string& version) { this->gVersion = version; }
239 std::string GetCurrentAssetName()
const {
return this->gCurrentAssetName; }
240 void SetAssetTotal(std::atomic<size_t>* total) { this->gAssetTotal = total; }
241 void SetPhaseCallback(std::function<
void(
int)> cb) { this->gPhaseCallback = cb; }
243 void SetProcess(
bool shouldProcess);
245 BinaryWrapper* GetCurrentWrapper() {
return this->gCurrentWrapper; }
246 const std::unordered_map<std::string, std::string>& GetModdedAssetPaths()
const {
return this->gModdedAssetPaths; }
248 std::optional<std::tuple<std::string, YAML::Node>> RegisterAsset(
const std::string& name, YAML::Node& node);
249 std::optional<YAML::Node> AddSubFileAsset(YAML::Node asset, std::string newFileName, CompressionType newCompressionType, uint32_t compressedSize = 0);
250 std::optional<YAML::Node> AddAsset(YAML::Node asset);
251 std::string GetCurrentDirectory()
const {
return gCurrentDirectory.generic_string(); }
252 void SetCompressedSegment(uint32_t segmentId, uint32_t compressedFileOffset, uint32_t offset);
253 bool GetCompressedSegmentOffset(uint32_t* addr);
255 void SetSingleYMLPath(
const std::string& path) { this->gSingleYMLPath = path; }
258 void RegisterUIFactory(
const std::string& type,
const std::shared_ptr<BaseFactoryUI>& factory);
259 std::optional<std::shared_ptr<BaseFactoryUI>> GetUIFactory(
const std::string& type);
260 const std::unordered_map<std::string, std::vector<ParseResultData>>& GetParseResults() {
return this->gParseResults; }
264 YAML::Node gModdingConfig;
265 fs::path gSourceDirectory;
266 fs::path gDestinationDirectory;
267 fs::path gCurrentDirectory;
268 std::string gCurrentHash;
269 std::string gAssetPath;
270 std::string gVersion;
271 std::string gSingleYMLPath;
272 std::vector<uint8_t> gRomData;
273 std::optional<std::filesystem::path> gRomPath;
274 bool gNodeForceProcessing =
false;
275 bool gIndividualIncludes =
false;
276 YAML::Node gHashNode;
277 std::shared_ptr<N64::Cartridge> gCartridge;
278 std::string gGameTitle;
279 std::unordered_map<std::string, std::vector<YAML::Node>> gCourseMetadata;
280 std::unordered_map<std::string, std::unordered_map<int32_t, std::string>> gEnums;
284 std::string gCurrentAssetName;
285 std::atomic<size_t>* gAssetCounter =
nullptr;
286 std::atomic<size_t>* gAssetTotal =
nullptr;
287 std::function<void(
int)> gPhaseCallback;
288 std::string gCurrentFile;
289 std::vector<std::string> gSubFileList;
290 std::string gCurrentVirtualPath;
291 std::string gFileHeader;
292 bool gEnablePadGen =
false;
293 bool mShouldProcess =
true;
294 uint32_t gCurrentPad = 0;
295 uint32_t gCurrentFileOffset;
296 uint32_t gCurrentSegmentNumber;
297 std::optional<VRAMEntry> gCurrentVram;
298 CompressionType gCurrentCompressionType = CompressionType::None;
299 std::optional<std::uint32_t> gCurrentCompressedSize;
300 std::vector<Table> gTables;
301 std::vector<std::string> gCurrentExternalFiles;
302 std::unordered_map<int, std::string> gManualSegments;
303 std::unordered_set<std::string> gProcessedFiles;
305 std::unordered_map<std::string, std::vector<char>> gCompanionFiles;
306 std::vector<std::pair<std::string, std::vector<char>>> gArchiveFiles;
307 std::unordered_map<std::string, std::vector<ParseResultData>> gParseResults;
308 std::vector<std::string> gAdditionalFiles;
310 std::unordered_map<std::string, std::string> gModdedAssetPaths;
311 std::variant<std::vector<std::string>, std::string> gWriteOrder;
312 std::unordered_map<std::string, std::shared_ptr<BaseFactory>> gFactories;
314 std::unordered_map<std::string, std::shared_ptr<BaseFactoryUI>> gUIFactories;
316 std::unordered_map<std::string, std::map<std::string, std::vector<WriteEntry>>> gWriteMap;
317 std::unordered_map<std::string, std::tuple<uint32_t, uint32_t>> gVirtualAddrMap;
318 std::unordered_map<std::string, std::unordered_map<uint32_t, std::tuple<std::string, YAML::Node>>> gAddrMap;
322 std::unordered_map<std::string,
323 std::unordered_map<std::string, std::array<std::vector<std::tuple<std::string, YAML::Node>>, 2>>>
326 std::unordered_map<std::string, std::unordered_map<std::string, uint8_t>> gNodesByTypeCacheValid;
328 void ProcessParseFile(YAML::Node root, std::atomic<size_t>& assetCount);
329 void ProcessExportFile();
330 void ProcessFile(YAML::Node root);
331 void ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount);
332 std::optional<std::tuple<std::string, YAML::Node>> FindNodeInOverlaySegments(uint32_t addr,
const std::string& file);
333 std::optional<std::tuple<std::string, YAML::Node>> FindInExternalByVRAM(uint32_t addr,
const std::string& file);
334 void ParseEnums(std::string& file);
336 void ParseModdingConfig();
337 void ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& assetCount);
338 void RegisterFactory(
const std::string& type,
const std::shared_ptr<BaseFactory>& factory);
339 void ExtractNode(YAML::Node& node, std::string& name,
BinaryWrapper* binary);
340 void ProcessTables(YAML::Node& rom);
341 void LoadYAMLRecursively(
const std::string &dirPath, std::vector<YAML::Node> &result,
bool skipRoot);
342 std::vector<fs::directory_entry> GetAssetYMLs(YAML::Node& rom)
const;
343 std::optional<ParseResultData> ParseNode(YAML::Node& node, std::string& name);