summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Companion.cpp9
-rw-r--r--src/Companion.h2
-rw-r--r--src/factories/oot/OoTAudioFactory.cpp33
-rw-r--r--src/factories/oot/OoTAudioFactory.h4
4 files changed, 33 insertions, 15 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp
index 74d6ec1..bb58dcf 100644
--- a/src/Companion.cpp
+++ b/src/Companion.cpp
@@ -536,7 +536,7 @@ void Companion::ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& ass
auto externalFile = externalFiles[i];
if (externalFile.size() == 0) {
this->gCurrentExternalFiles.push_back(
- (this->gSourceDirectory / externalFile.as<std::string>()).string());
+ (this->gSourceDirectory / externalFile.as<std::string>()).generic_string());
} else {
SPDLOG_INFO("External File size {}", externalFile.size());
throw std::runtime_error(
@@ -544,9 +544,10 @@ void Companion::ParseCurrentFileConfig(YAML::Node node, std::atomic<size_t>& ass
" - <external_files>\n\ne.g.:\nexternal_files:\n - actors/actor1.yaml");
}
- std::string externalFileName = (this->gSourceDirectory / externalFile.as<std::string>()).string();
- if (StringHelper::StartsWith(std::filesystem::relative(externalFileName, this->gAssetPath).string(),
- "../")) {
+ std::string externalFileName =
+ (this->gSourceDirectory / externalFile.as<std::string>()).generic_string();
+ if (StringHelper::StartsWith(
+ std::filesystem::relative(externalFileName, this->gAssetPath).generic_string(), "../")) {
throw std::runtime_error("External File " + externalFileName + " Not In Asset Directory " +
this->gAssetPath);
} else if (std::filesystem::relative(externalFileName, this->gAssetPath).string() == "") {
diff --git a/src/Companion.h b/src/Companion.h
index 2b28a8e..5bdfb49 100644
--- a/src/Companion.h
+++ b/src/Companion.h
@@ -248,7 +248,7 @@ public:
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);
- std::string GetCurrentDirectory() const { return gCurrentDirectory.string(); }
+ std::string GetCurrentDirectory() const { return gCurrentDirectory.generic_string(); }
void SetCompressedSegment(uint32_t segmentId, uint32_t compressedFileOffset, uint32_t offset);
bool GetCompressedSegmentOffset(uint32_t* addr);
diff --git a/src/factories/oot/OoTAudioFactory.cpp b/src/factories/oot/OoTAudioFactory.cpp
index f4b1d6d..2c0465d 100644
--- a/src/factories/oot/OoTAudioFactory.cpp
+++ b/src/factories/oot/OoTAudioFactory.cpp
@@ -5,12 +5,23 @@
#include "spdlog/spdlog.h"
#include "Companion.h"
#include "utils/Decompressor.h"
+#include <algorithm>
#include <sstream>
namespace OoT {
-std::vector<AudioTableEntry> OoTAudioFactory::ParseAudioTable(const uint8_t* codeData, uint32_t tableOffset) {
- LUS::BinaryReader reader((char*)(codeData + tableOffset), 0x10000);
+// BinaryReader copies its whole window up front, so the window must not run past the segment.
+static size_t TableWindow(size_t segmentSize, uint32_t tableOffset) {
+ if (tableOffset >= segmentSize) {
+ throw std::runtime_error("Audio table offset 0x" + fmt::format("{:X}", tableOffset) +
+ " is outside the 0x" + fmt::format("{:X}", segmentSize) + " byte code segment");
+ }
+ return std::min<size_t>(segmentSize - tableOffset, 0x10000);
+}
+
+std::vector<AudioTableEntry> OoTAudioFactory::ParseAudioTable(const uint8_t* codeData, size_t segmentSize,
+ uint32_t tableOffset) {
+ LUS::BinaryReader reader((char*)(codeData + tableOffset), TableWindow(segmentSize, tableOffset));
reader.SetEndianness(Torch::Endianness::Big);
uint16_t numEntries = reader.ReadUInt16();
@@ -36,11 +47,11 @@ std::vector<AudioTableEntry> OoTAudioFactory::ParseAudioTable(const uint8_t* cod
}
std::vector<std::vector<uint8_t>> OoTAudioFactory::ParseSequenceFontTable(
- const uint8_t* codeData, uint32_t tableOffset, uint32_t numSequences) {
+ const uint8_t* codeData, size_t segmentSize, uint32_t tableOffset, uint32_t numSequences) {
std::vector<std::vector<uint8_t>> result;
result.reserve(numSequences);
- LUS::BinaryReader reader((char*)(codeData + tableOffset), 0x10000);
+ LUS::BinaryReader reader((char*)(codeData + tableOffset), TableWindow(segmentSize, tableOffset));
reader.SetEndianness(Torch::Endianness::Big);
std::vector<uint16_t> offsets;
@@ -92,10 +103,16 @@ std::optional<std::shared_ptr<IParsedData>> OoTAudioFactory::parse(std::vector<u
buffer);
// Parse audio tables from code segment at YAML-specified offsets
- auto seqTable = ParseAudioTable(codeDecoded.segment.data, GetSafeNode<uint32_t>(node, "sequence_table_offset"));
- auto fontTable = ParseAudioTable(codeDecoded.segment.data, GetSafeNode<uint32_t>(node, "sound_font_table_offset"));
- auto sampleBankTable = ParseAudioTable(codeDecoded.segment.data, GetSafeNode<uint32_t>(node, "sample_bank_table_offset"));
- auto seqFontMap = ParseSequenceFontTable(codeDecoded.segment.data, GetSafeNode<uint32_t>(node, "sequence_font_table_offset"), seqTable.size());
+ const size_t codeSize = codeDecoded.segment.size;
+ auto seqTable =
+ ParseAudioTable(codeDecoded.segment.data, codeSize, GetSafeNode<uint32_t>(node, "sequence_table_offset"));
+ auto fontTable =
+ ParseAudioTable(codeDecoded.segment.data, codeSize, GetSafeNode<uint32_t>(node, "sound_font_table_offset"));
+ auto sampleBankTable =
+ ParseAudioTable(codeDecoded.segment.data, codeSize, GetSafeNode<uint32_t>(node, "sample_bank_table_offset"));
+ auto seqFontMap = ParseSequenceFontTable(codeDecoded.segment.data, codeSize,
+ GetSafeNode<uint32_t>(node, "sequence_font_table_offset"),
+ seqTable.size());
SPDLOG_INFO("OoTAudioFactory: {} sequences, {} fonts, {} sample banks",
seqTable.size(), fontTable.size(), sampleBankTable.size());
diff --git a/src/factories/oot/OoTAudioFactory.h b/src/factories/oot/OoTAudioFactory.h
index 376a761..31a83e8 100644
--- a/src/factories/oot/OoTAudioFactory.h
+++ b/src/factories/oot/OoTAudioFactory.h
@@ -26,8 +26,8 @@ public:
private:
std::vector<char> BuildMainAudioHeader();
std::optional<SafeAudioBankReader> LoadAudioBank(std::vector<uint8_t>& buffer);
- std::vector<AudioTableEntry> ParseAudioTable(const uint8_t* codeData, uint32_t tableOffset);
- std::vector<std::vector<uint8_t>> ParseSequenceFontTable(const uint8_t* codeData,
+ std::vector<AudioTableEntry> ParseAudioTable(const uint8_t* codeData, size_t segmentSize, uint32_t tableOffset);
+ std::vector<std::vector<uint8_t>> ParseSequenceFontTable(const uint8_t* codeData, size_t segmentSize,
uint32_t tableOffset, uint32_t numSequences);
};