summaryrefslogtreecommitdiff
path: root/src/Companion.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Companion.h')
-rw-r--r--src/Companion.h53
1 files changed, 47 insertions, 6 deletions
diff --git a/src/Companion.h b/src/Companion.h
index eb6de7d..f8bcd68 100644
--- a/src/Companion.h
+++ b/src/Companion.h
@@ -5,10 +5,12 @@
#include <filesystem>
#include <vector>
#include <atomic>
+#include <array>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <variant>
+#include <functional>
#include "factories/BaseFactory.h"
#include "n64/Cartridge.h"
#include "utils/Decompressor.h"
@@ -36,7 +38,8 @@ enum class GBIMinorVersion {
None,
Mk64,
SM64,
- PM64
+ PM64,
+ BK64
};
enum class TableMode {
@@ -54,6 +57,7 @@ struct SegmentConfig {
std::unordered_map<uint32_t, uint32_t> global;
std::unordered_map<uint32_t, uint32_t> local;
std::unordered_map<uint32_t, uint32_t> temporal;
+ std::unordered_map<std::string, std::unordered_map<uint32_t, std::pair<std::uint32_t, std::uint32_t>>> compressed;
};
struct Table {
@@ -95,6 +99,8 @@ struct TorchConfig {
bool debug;
bool modding;
bool textureDefines;
+ bool includeAutogen;
+ bool dialogPack = false;
};
struct ParseResultData {
@@ -124,6 +130,7 @@ public:
this->gConfig.debug = debug;
this->gConfig.modding = modding;
this->gConfig.textureDefines = false;
+ this->gConfig.includeAutogen = false;
}
explicit Companion(std::vector<uint8_t> rom, const ArchiveType otr, const bool debug, const bool modding = false,
@@ -134,8 +141,11 @@ public:
this->gConfig.debug = debug;
this->gConfig.modding = modding;
this->gConfig.textureDefines = false;
+ this->gConfig.includeAutogen = false;
}
+ void SetRomPath(std::filesystem::path path) { this->gRomPath = std::move(path); }
+
explicit Companion(std::filesystem::path rom, const ArchiveType otr, const bool debug, const std::string& srcDir = "", const std::string& destPath = "") :
Companion(rom, otr, debug, false, srcDir, destPath) {}
@@ -143,7 +153,7 @@ public:
Companion(rom, otr, debug, false, srcDir, destPath) {}
void Init(ExportType type);
- void Init(ExportType type, std::atomic<size_t>& assetCount);
+ void Init(ExportType type, std::atomic<size_t>& assetCount, bool shouldProcess);
bool NodeHasChanges(const std::string& string);
@@ -156,6 +166,7 @@ public:
N64::Cartridge* GetCartridge() const { return this->gCartridge.get(); }
std::vector<uint8_t>& GetRomData() { return this->gRomData; }
std::string GetOutputPath() { return this->gConfig.outputPath; }
+ const std::string& GetAssetPath() const { return this->gAssetPath; }
std::string GetDestRelativeOutputPath() { return RelativePathToDestDir(GetOutputPath()); }
GBIVersion GetGBIVersion() const { return this->gConfig.gbi.version; }
@@ -168,18 +179,25 @@ public:
std::optional<ParseResultData> GetParseDataBySymbol(const std::string& symbol);
std::optional<std::uint32_t> GetFileOffsetFromSegmentedAddr(uint8_t segment) const;
+ std::optional<std::pair<std::uint32_t, std::uint32_t>> GetFileOffsetFromCompressedSegmentedAddr(uint8_t segment) const;
std::optional<std::shared_ptr<BaseFactory>> GetFactory(const std::string& type);
uint32_t PatchVirtualAddr(uint32_t addr);
std::optional<std::tuple<std::string, YAML::Node>> GetNodeByAddr(uint32_t addr);
std::optional<std::string> GetStringByAddr(uint32_t addr);
std::optional<std::tuple<std::string, YAML::Node>> GetSafeNodeByAddr(const uint32_t addr, std::string type);
std::optional<std::string> GetSafeStringByAddr(const uint32_t addr, std::string type);
- std::optional<std::vector<std::tuple<std::string, YAML::Node>>> GetNodesByType(const std::string& type);
+ std::optional<std::vector<std::tuple<std::string, YAML::Node>>> GetNodesByType(const std::string& type, bool includeAutogen = false);
+ // Same as GetNodesByType but returns a pointer into the internal cache to
+ // avoid copying. The pointer is valid until the cache is invalidated; do not
+ // hold across AddAsset/RegisterAsset calls. Returns nullptr if the current
+ // file has no nodes registered.
+ const std::vector<std::tuple<std::string, YAML::Node>>* GetNodesByTypeRef(const std::string& type, bool includeAutogen = false);
std::string GetSymbolFromAddr(uint32_t addr, bool validZero = false);
std::optional<std::uint32_t> GetFileOffset(void) const { return this->gCurrentFileOffset; };
std::optional<std::uint32_t> GetCurrSegmentNumber(void) const { return this->gCurrentSegmentNumber; };
CompressionType GetCurrCompressionType(void) const { return this->gCurrentCompressionType; };
+ std::optional<std::uint32_t> GetCurrentCompressedSize(void) const { return this->gCurrentCompressedSize; };
std::optional<VRAMEntry> GetCurrentVRAM(void) const { return this->gCurrentVram; };
std::optional<Table> SearchTable(uint32_t addr);
@@ -194,13 +212,19 @@ public:
void SetAdditionalFiles(const std::vector<std::string>& files) { this->gAdditionalFiles = files; }
void SetVersion(const std::string& version) { this->gVersion = version; }
+ std::string GetCurrentAssetName() const { return this->gCurrentAssetName; }
+ void SetAssetTotal(std::atomic<size_t>* total) { this->gAssetTotal = total; }
+ void SetPhaseCallback(std::function<void(int)> cb) { this->gPhaseCallback = cb; }
+
void SetProcess(bool shouldProcess);
TorchConfig& GetConfig() { return this->gConfig; }
BinaryWrapper* GetCurrentWrapper() { return this->gCurrentWrapper; }
std::optional<std::tuple<std::string, YAML::Node>> RegisterAsset(const std::string& name, YAML::Node& node);
+ std::optional<YAML::Node> AddSubFileAsset(YAML::Node asset, std::string newFileName, CompressionType newCompressionType, uint32_t compressedSize = 0);
std::optional<YAML::Node> AddAsset(YAML::Node asset);
- void RegisterFactory(const std::string& type, const std::shared_ptr<BaseFactory>& factory);
+ void SetCompressedSegment(uint32_t segmentId, uint32_t compressedFileOffset, uint32_t offset);
+ bool GetCompressedSegmentOffset(uint32_t* addr);
private:
TorchConfig gConfig;
YAML::Node gModdingConfig;
@@ -221,16 +245,22 @@ private:
BinaryWrapper* gCurrentWrapper;
// Temporal Variables
+ std::string gCurrentAssetName;
+ std::atomic<size_t>* gAssetCounter = nullptr;
+ std::atomic<size_t>* gAssetTotal = nullptr;
+ std::function<void(int)> gPhaseCallback;
std::string gCurrentFile;
+ std::vector<std::string> gSubFileList;
std::string gCurrentVirtualPath;
std::string gFileHeader;
bool gEnablePadGen = false;
- bool process = true;
+ bool mShouldProcess = true;
uint32_t gCurrentPad = 0;
uint32_t gCurrentFileOffset;
uint32_t gCurrentSegmentNumber;
std::optional<VRAMEntry> gCurrentVram;
CompressionType gCurrentCompressionType = CompressionType::None;
+ std::optional<std::uint32_t> gCurrentCompressedSize;
std::vector<Table> gTables;
std::vector<std::string> gCurrentExternalFiles;
std::unordered_map<int, std::string> gManualSegments;
@@ -246,13 +276,24 @@ private:
std::unordered_map<std::string, std::map<std::string, std::vector<WriteEntry>>> gWriteMap;
std::unordered_map<std::string, std::tuple<uint32_t, uint32_t>> gVirtualAddrMap;
std::unordered_map<std::string, std::unordered_map<uint32_t, std::tuple<std::string, YAML::Node>>> gAddrMap;
-
+ // Cached results of GetNodesByType keyed by [file][type][includeAutogen?].
+ // Built lazily; invalidated on RegisterAsset for the affected (file, type).
+ // Index 0 = !includeAutogen, index 1 = includeAutogen.
+ std::unordered_map<std::string,
+ std::unordered_map<std::string, std::array<std::vector<std::tuple<std::string, YAML::Node>>, 2>>>
+ gNodesByTypeCache;
+ // Validity bitmap; bit 0 = !includeAutogen, bit 1 = includeAutogen.
+ std::unordered_map<std::string, std::unordered_map<std::string, uint8_t>> gNodesByTypeCacheValid;
+
+ void ProcessParseFile(YAML::Node root, std::atomic<size_t>& assetCount);
+ void ProcessExportFile();
void ProcessFile(YAML::Node root);
void ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount);
void ParseEnums(std::string& file);
void ParseHash();
void ParseModdingConfig();
void ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& assetCount);
+ void RegisterFactory(const std::string& type, const std::shared_ptr<BaseFactory>& factory);
void ExtractNode(YAML::Node& node, std::string& name, BinaryWrapper* binary);
void ProcessTables(YAML::Node& rom);
void LoadYAMLRecursively(const std::string &dirPath, std::vector<YAML::Node> &result, bool skipRoot);