summaryrefslogtreecommitdiff
path: root/src/Companion.cpp
diff options
context:
space:
mode:
authorlouist103 <35883445+louist103@users.noreply.github.com>2026-08-20 18:13:41 +0000
committerGitHub <noreply@github.com>2026-08-20 14:13:41 -0400
commit098f88d078a900c7292af56b94269baaafe8c3eb (patch)
tree9ce2cae03b7687704d77331e1c9347ddb4e140b6 /src/Companion.cpp
parentf3804f1e092b9277d0b475832f7e5357245f95ed (diff)
Add support for reading offsets from an external file (#253)
* Add support for reading offsets from a symbol and file list * Review throw message * Use IsValidOffset instead of IsValidHex
Diffstat (limited to 'src/Companion.cpp')
-rw-r--r--src/Companion.cpp68
1 files changed, 56 insertions, 12 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp
index d73b616..e0c423d 100644
--- a/src/Companion.cpp
+++ b/src/Companion.cpp
@@ -620,16 +620,17 @@ void Companion::ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& ass
// Set global variables for segmented data
if (segments.IsSequence() && segments.size()) {
if (segments[0].IsSequence() && segments[0].size() == 2) {
- gCurrentSegmentNumber = segments[0][0].as<uint32_t>();
- gCurrentFileOffset = segments[0][1].as<uint32_t>();
+ SetSegmentInfo(segments);
+
gCurrentCompressionType = Decompressor::GetCompressionType(this->gRomData, gCurrentFileOffset);
if (node["no_compression"]) {
gCurrentCompressionType = CompressionType::None;
}
} else {
throw std::runtime_error(
- "Incorrect yaml syntax for segments.\n\nThe yaml expects:\n:config:\n segments:\n - [<segment>, "
- "<file_offset>]\n\nLike so:\nsegments:\n - [0x06, 0x821D10]");
+ "Incorrect yaml syntax for segments.\n\nThe yaml expects:\n:config:\n segments:\n - [<segment>, "
+ "<file_offset>] or - [<segment>, "
+ "<file_name>] \n\nLike so:\nsegments:\n - [0x06, 0x821D10] or [0x06, object_jya_obj");
}
}
@@ -638,13 +639,14 @@ void Companion::ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& ass
auto segment = segments[i];
if (segment.IsSequence() && segment.size() == 2) {
const auto id = segment[0].as<uint32_t>();
- const auto replacement = segment[1].as<uint32_t>();
+ const auto replacement = GetFileOffsetFromNodeStr(segment[1].as<std::string>());
this->gConfig.segment.local[id] = replacement;
SPDLOG_DEBUG("Segment {} replaced with 0x{:X}", id, replacement);
} else {
throw std::runtime_error(
"Incorrect yaml syntax for segments.\n\nThe yaml expects:\n:config:\n segments:\n - [<segment>, "
- "<file_offset>]\n\nLike so:\nsegments:\n - [0x06, 0x821D10]");
+ "<file_offset>] or - [<segment>, "
+ "<file_name>] \n\nLike so:\nsegments:\n - [0x06, 0x821D10] or [0x06, object_jya_obj");
}
}
}
@@ -1183,6 +1185,19 @@ void Companion::ProcessExportFile() {
}
}
+void Companion::SetSegmentInfo(const YAML::Node& segments) {
+ gCurrentSegmentNumber = segments[0][0].as<uint32_t>();
+
+ const auto offsetNode = segments[0][1].as<std::string>();
+ gCurrentFileOffset = GetFileOffsetFromNodeStr(offsetNode);
+}
+
+uint32_t Companion::GetFileOffsetFromNodeStr(const std::string& str) const {
+ if (StringHelper::IsValidOffset(str))
+ return strtoul(str.c_str(), nullptr, 16);
+ return GetFileOffsetFromName(str);
+}
+
void Companion::ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount) {
// Reset per-file state so segment/offset settings from a previous file don't
// bleed into this file's Phase 1 gAddrMap registration.
@@ -1201,8 +1216,8 @@ void Companion::ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount) {
if (auto segments = root[":config"]["segments"]) {
if (segments.IsSequence() && segments.size() > 0) {
if (segments[0].IsSequence() && segments[0].size() == 2) {
- gCurrentSegmentNumber = segments[0][0].as<uint32_t>();
- gCurrentFileOffset = segments[0][1].as<uint32_t>();
+ SetSegmentInfo(segments);
+
gCurrentCompressionType = Decompressor::GetCompressionType(this->gRomData, gCurrentFileOffset);
if (root[":config"]["no_compression"]) {
gCurrentCompressionType = CompressionType::None;
@@ -1210,7 +1225,8 @@ void Companion::ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount) {
} else {
throw std::runtime_error(
"Incorrect yaml syntax for segments.\n\nThe yaml expects:\n:config:\n segments:\n - [<segment>, "
- "<file_offset>]\n\nLike so:\nsegments:\n - [0x06, 0x821D10]");
+ "<file_offset>] or - [<segment>, "
+ "<file_name>] \n\nLike so:\nsegments:\n - [0x06, 0x821D10] or [0x06, object_jya_obj");
}
}
}
@@ -1234,9 +1250,14 @@ void Companion::ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount) {
continue;
}
+ auto offset = GetFileOffsetFromNodeStr(node["offset"].as<std::string>());
+
if (gCurrentSegmentNumber) {
- if (IS_SEGMENTED(node["offset"].as<uint32_t>()) == false) {
- node["offset"] = (gCurrentSegmentNumber << 24) | node["offset"].as<uint32_t>();
+
+ if (IS_SEGMENTED(offset) == false) {
+ offset = (gCurrentSegmentNumber << 24) | offset;
+ node["offset"] = offset;
+
}
}
@@ -1244,7 +1265,7 @@ void Companion::ProcessFile(YAML::Node root, std::atomic<size_t>& assetCount) {
node["path"] = gCurrentVirtualPath;
}
- this->gAddrMap[this->gCurrentFile][node["offset"].as<uint32_t>()] = std::make_tuple(output, node);
+ this->gAddrMap[this->gCurrentFile][offset] = std::make_tuple(output, node);
}
// Stupid hack because the iteration broke the assets
@@ -1414,6 +1435,16 @@ void Companion::Process(std::atomic<size_t>& assetCount) {
}
}
this->gAssetPath = (this->gSourceDirectory / rom["path"].as<std::string>()).string();
+
+ if (rom["filelist"]) {
+ const std::string filelistPath = (this->gSourceDirectory / rom["filelist"].as<std::string>()).string();
+ if (!fs::exists(filelistPath)) {
+ SPDLOG_ERROR("A filelist was specified but the file doesn't exist");
+ return;
+ }
+ ParseFilelist(filelistPath);
+ }
+
auto opath = cfg["output"];
auto gbi = cfg["gbi"];
auto gbi_floats = cfg["gbi_floats"];
@@ -2590,3 +2621,16 @@ bool Companion::GetCompressedSegmentOffset(uint32_t* addr) {
}
return false;
}
+
+void Companion::ParseFilelist(const std::string& filelistPath) {
+ YAML::Node root = YAML::LoadFile(filelistPath);
+
+ for (const auto f : root["Files"]) {
+ for (const auto& kv : f) {
+ const auto file = kv.first.as<std::string>();
+ const auto offset = kv.second.as<uint32_t>();
+ gFileOffsets[file] = offset;
+ }
+
+ }
+}