Torch
Loading...
Searching...
No Matches
Companion.h
1#pragma once
2
3#include <string>
4#include <optional>
5#include <filesystem>
6#include <vector>
7#include <atomic>
8#include <fstream>
9#include <unordered_map>
10#include <unordered_set>
11#include <variant>
12#include "factories/BaseFactory.h"
13#include "n64/Cartridge.h"
14#include "utils/Decompressor.h"
15#include "factories/TextureFactory.h"
16
17#define CONTAINS(_map, value) ((_map).find(value) != (_map).end())
18
19class BinaryWrapper;
20namespace fs = std::filesystem;
21
22enum class ParseMode {
23 Default,
24 Directory
25};
26
27enum class GBIVersion {
28 f3db,
29 f3d,
30 f3dex,
31 f3dexb,
32 f3dex2,
33};
34
35enum class GBIMinorVersion {
36 None,
37 Mk64,
38 SM64,
39 PM64
40};
41
42enum class TableMode {
43 Reference,
44 Append
45};
46
47enum class ArchiveType {
48 None,
49 OTR,
50 O2R,
51};
52
54 std::unordered_map<uint32_t, uint32_t> global;
55 std::unordered_map<uint32_t, uint32_t> local;
56 std::unordered_map<uint32_t, uint32_t> temporal;
57};
58
59struct Table {
60 std::string name;
61 uint32_t start;
62 uint32_t end;
63 TableMode mode;
64 int32_t index_size;
65};
66
67struct VRAMEntry {
68 uint32_t addr;
69 uint32_t offset;
70};
71
72struct WriteEntry {
73 std::string name;
74 uint32_t addr;
75 uint32_t alignment;
76 std::string buffer;
77 std::optional<std::string> comment;
78 std::optional<uint32_t> endptr;
79};
80
81struct GBIConfig {
82 GBIVersion version = GBIVersion::f3d;
83 GBIMinorVersion subversion = GBIMinorVersion::None;
84 bool useFloats = false;
85};
86
88 GBIConfig gbi;
89 SegmentConfig segment;
90 std::string outputPath;
91 std::string moddingPath;
92 ExportType exporterType;
93 ParseMode parseMode;
94 ArchiveType otrMode;
95 bool debug;
96 bool modding;
97 bool textureDefines;
98};
99
101 std::string name;
102 std::string type;
103 YAML::Node node;
104 std::optional<std::shared_ptr<IParsedData>> data;
105
106 uint32_t GetOffset() {
107 return GetSafeNode<uint32_t>(node, "offset");
108 }
109
110 std::optional<std::string> GetSymbol() {
111 return GetSafeNode<std::string>(node, "symbol");
112 }
113};
114
115class Companion {
116public:
117 static Companion* Instance;
118
119 explicit Companion(std::filesystem::path rom, const ArchiveType otr, const bool debug, const bool modding = false,
120 const std::string& srcDir = "", const std::string& destPath = "") : gCartridge(nullptr),
121 gSourceDirectory(srcDir), gDestinationDirectory(destPath) {
122 this->gRomPath = rom;
123 this->gConfig.otrMode = otr;
124 this->gConfig.debug = debug;
125 this->gConfig.modding = modding;
126 this->gConfig.textureDefines = false;
127 }
128
129 explicit Companion(std::vector<uint8_t> rom, const ArchiveType otr, const bool debug, const bool modding = false,
130 const std::string& srcDir = "", const std::string& destPath = "") : gCartridge(nullptr),
131 gSourceDirectory(srcDir), gDestinationDirectory(destPath) {
132 this->gRomData = rom;
133 this->gConfig.otrMode = otr;
134 this->gConfig.debug = debug;
135 this->gConfig.modding = modding;
136 this->gConfig.textureDefines = false;
137 }
138
139 explicit Companion(std::filesystem::path rom, const ArchiveType otr, const bool debug, const std::string& srcDir = "", const std::string& destPath = "") :
140 Companion(rom, otr, debug, false, srcDir, destPath) {}
141
142 explicit Companion(std::vector<uint8_t> rom, const ArchiveType otr, const bool debug, const std::string& srcDir = "", const std::string& destPath = "") :
143 Companion(rom, otr, debug, false, srcDir, destPath) {}
144
145 void Init(ExportType type);
146 void Init(ExportType type, std::atomic<size_t>& assetCount);
147
148 bool NodeHasChanges(const std::string& string);
149
150 void Process(std::atomic<size_t>& assetCount);
151
152 bool IsOTRMode() const { return (this->gConfig.otrMode != ArchiveType::None); }
153 bool IsDebug() const { return this->gConfig.debug; }
154 bool AddTextureDefines() const { return this->gConfig.textureDefines; }
155
156 N64::Cartridge* GetCartridge() const { return this->gCartridge.get(); }
157 std::vector<uint8_t>& GetRomData() { return this->gRomData; }
158 std::string GetOutputPath() { return this->gConfig.outputPath; }
159 std::string GetDestRelativeOutputPath() { return RelativePathToDestDir(GetOutputPath()); }
160
161 GBIVersion GetGBIVersion() const { return this->gConfig.gbi.version; }
162 GBIMinorVersion GetGBIMinorVersion() const { return this->gConfig.gbi.subversion; }
163 std::unordered_map<std::string, std::vector<YAML::Node>> GetCourseMetadata() { return this->gCourseMetadata; }
164 std::optional<std::string> GetEnumFromValue(const std::string& key, int id);
165 bool IsUsingIndividualIncludes() const { return this->gIndividualIncludes; }
166
167 std::optional<ParseResultData> GetParseDataByAddr(uint32_t addr);
168 std::optional<ParseResultData> GetParseDataBySymbol(const std::string& symbol);
169
170 std::optional<std::uint32_t> GetFileOffsetFromSegmentedAddr(uint8_t segment) const;
171 std::optional<std::shared_ptr<BaseFactory>> GetFactory(const std::string& type);
172 uint32_t PatchVirtualAddr(uint32_t addr);
173 std::optional<std::tuple<std::string, YAML::Node>> GetNodeByAddr(uint32_t addr);
174 std::optional<std::string> GetStringByAddr(uint32_t addr);
175 std::optional<std::tuple<std::string, YAML::Node>> GetSafeNodeByAddr(const uint32_t addr, std::string type);
176 std::optional<std::string> GetSafeStringByAddr(const uint32_t addr, std::string type);
177 std::optional<std::vector<std::tuple<std::string, YAML::Node>>> GetNodesByType(const std::string& type);
178 std::string GetSymbolFromAddr(uint32_t addr, bool validZero = false);
179
180 std::optional<std::uint32_t> GetFileOffset(void) const { return this->gCurrentFileOffset; };
181 std::optional<std::uint32_t> GetCurrSegmentNumber(void) const { return this->gCurrentSegmentNumber; };
182 CompressionType GetCurrCompressionType(void) const { return this->gCurrentCompressionType; };
183 std::optional<VRAMEntry> GetCurrentVRAM(void) const { return this->gCurrentVram; };
184 std::optional<Table> SearchTable(uint32_t addr);
185
186 static std::vector<char> ParseVersionString(const std::string& version);
187 static std::string CalculateHash(const std::vector<uint8_t>& data);
188 static void Pack(const std::string& folder, const std::string& output, const ArchiveType otrMode, const std::string& version = "");
189 std::string NormalizeAsset(const std::string& name) const;
190 std::string RelativePath(const std::string& path) const;
191 std::string RelativePathToSrcDir(const std::string& path) const;
192 std::string RelativePathToDestDir(const std::string& path) const;
193 void RegisterCompanionFile(const std::string path, std::vector<char> data);
194 void SetAdditionalFiles(const std::vector<std::string>& files) { this->gAdditionalFiles = files; }
195 void SetVersion(const std::string& version) { this->gVersion = version; }
196
197 void SetProcess(bool shouldProcess);
198 TorchConfig& GetConfig() { return this->gConfig; }
199 BinaryWrapper* GetCurrentWrapper() { return this->gCurrentWrapper; }
200
201 std::optional<std::tuple<std::string, YAML::Node>> RegisterAsset(const std::string& name, YAML::Node& node);
202 std::optional<YAML::Node> AddAsset(YAML::Node asset);
203 void RegisterFactory(const std::string& type, const std::shared_ptr<BaseFactory>& factory);
204private:
205 TorchConfig gConfig;
206 YAML::Node gModdingConfig;
207 fs::path gSourceDirectory;
208 fs::path gDestinationDirectory;
209 fs::path gCurrentDirectory;
210 std::string gCurrentHash;
211 std::string gAssetPath;
212 std::string gVersion;
213 std::vector<uint8_t> gRomData;
214 std::optional<std::filesystem::path> gRomPath;
215 bool gNodeForceProcessing = false;
216 bool gIndividualIncludes = false;
217 YAML::Node gHashNode;
218 std::shared_ptr<N64::Cartridge> gCartridge;
219 std::unordered_map<std::string, std::vector<YAML::Node>> gCourseMetadata;
220 std::unordered_map<std::string, std::unordered_map<int32_t, std::string>> gEnums;
221 BinaryWrapper* gCurrentWrapper;
222
223 // Temporal Variables
224 std::string gCurrentFile;
225 std::string gCurrentVirtualPath;
226 std::string gFileHeader;
227 bool gEnablePadGen = false;
228 bool process = true;
229 uint32_t gCurrentPad = 0;
230 uint32_t gCurrentFileOffset;
231 uint32_t gCurrentSegmentNumber;
232 std::optional<VRAMEntry> gCurrentVram;
233 CompressionType gCurrentCompressionType = CompressionType::None;
234 std::vector<Table> gTables;
235 std::vector<std::string> gCurrentExternalFiles;
236 std::unordered_map<int, std::string> gManualSegments;
237 std::unordered_set<std::string> gProcessedFiles;
238
239 std::unordered_map<std::string, std::vector<char>> gCompanionFiles;
240 std::unordered_map<std::string, std::vector<ParseResultData>> gParseResults;
241 std::vector<std::string> gAdditionalFiles;
242
243 std::unordered_map<std::string, std::string> gModdedAssetPaths;
244 std::variant<std::vector<std::string>, std::string> gWriteOrder;
245 std::unordered_map<std::string, std::shared_ptr<BaseFactory>> gFactories;
246 std::unordered_map<std::string, std::map<std::string, std::vector<WriteEntry>>> gWriteMap;
247 std::unordered_map<std::string, std::tuple<uint32_t, uint32_t>> gVirtualAddrMap;
248 std::unordered_map<std::string, std::unordered_map<uint32_t, std::tuple<std::string, YAML::Node>>> gAddrMap;
249
250 void ProcessFile(YAML::Node root);
251 void ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount);
252 void ParseEnums(std::string& file);
253 void ParseHash();
254 void ParseModdingConfig();
255 void ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& assetCount);
256 void ExtractNode(YAML::Node& node, std::string& name, BinaryWrapper* binary);
257 void ProcessTables(YAML::Node& rom);
258 void LoadYAMLRecursively(const std::string &dirPath, std::vector<YAML::Node> &result, bool skipRoot);
259 std::optional<ParseResultData> ParseNode(YAML::Node& node, std::string& name);
260};
Definition BinaryWrapper.h:7
Definition Cartridge.h:15
Definition Companion.h:81
Definition Companion.h:100
Definition Companion.h:53
Definition Companion.h:59
Definition Companion.h:87
Definition Companion.h:67
Definition Companion.h:72