diff options
| author | KiritoDv <kiritodev01@gmail.com> | 2024-01-30 23:03:23 -0600 |
|---|---|---|
| committer | Lywx <kiritodev01@gmail.com> | 2024-01-31 12:05:40 -0600 |
| commit | 4668cf08fb240da4abaafc073ba08d9d13ac0fa5 (patch) | |
| tree | 8ef2781da88920eeb1267225e73406e25a3c17b6 /src | |
| parent | 242f8acf212d143443dc2ce846507bdb82571902 (diff) | |
Refactored code and added per file config
Diffstat (limited to 'src')
| -rw-r--r-- | src/Companion.cpp | 6 | ||||
| -rw-r--r-- | src/factories/BankFactory.cpp | 1 | ||||
| -rw-r--r-- | src/factories/BaseFactory.h | 27 | ||||
| -rw-r--r-- | src/factories/BlobFactory.cpp | 20 | ||||
| -rw-r--r-- | src/factories/DisplayListFactory.cpp | 160 | ||||
| -rw-r--r-- | src/factories/DisplayListOverrides.cpp | 10 | ||||
| -rw-r--r-- | src/factories/LightsFactory.cpp | 16 | ||||
| -rw-r--r-- | src/factories/SampleFactory.cpp | 1 | ||||
| -rw-r--r-- | src/factories/SequenceFactory.cpp | 13 | ||||
| -rw-r--r-- | src/factories/TextureFactory.cpp | 40 | ||||
| -rw-r--r-- | src/factories/VtxFactory.cpp | 16 | ||||
| -rw-r--r-- | src/factories/mk64/WaypointFactory.cpp | 14 | ||||
| -rw-r--r-- | src/factories/sm64/AnimationFactory.cpp | 19 | ||||
| -rw-r--r-- | src/factories/sm64/DialogFactory.cpp | 16 | ||||
| -rw-r--r-- | src/factories/sm64/DictionaryFactory.cpp | 11 | ||||
| -rw-r--r-- | src/factories/sm64/GeoLayoutFactory.cpp | 3 | ||||
| -rw-r--r-- | src/factories/sm64/Original.old | 485 | ||||
| -rw-r--r-- | src/factories/sm64/TextFactory.cpp | 14 | ||||
| -rw-r--r-- | src/utils/Decompressor.cpp | 124 | ||||
| -rw-r--r-- | src/utils/Decompressor.h | 36 | ||||
| -rw-r--r-- | src/utils/MIODecoder.cpp | 28 | ||||
| -rw-r--r-- | src/utils/MIODecoder.h | 12 |
22 files changed, 321 insertions, 751 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp index 17f4862..be70629 100644 --- a/src/Companion.cpp +++ b/src/Companion.cpp @@ -1,7 +1,7 @@ #include "Companion.h" #include "storm/SWrapper.h" -#include "utils/MIODecoder.h" +#include "utils/Decompressor.h" #include "factories/sm64/AnimationFactory.h" #include "factories/sm64/DialogFactory.h" #include "factories/sm64/DictionaryFactory.h" @@ -61,7 +61,7 @@ void Companion::Init(const ExportType type) { void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binary) { std::ostringstream stream; - auto type = node["type"].as<std::string>(); + auto type = GetSafeNode<std::string>(node, "type"); std::transform(type.begin(), type.end(), type.begin(), ::toupper); if(node["offset"]) { @@ -408,7 +408,7 @@ void Companion::Process() { spdlog::set_pattern(regular); SPDLOG_INFO("------------------------------------------------"); - MIO0Decoder::ClearCache(); + Decompressor::ClearCache(); this->gCartridge = nullptr; Instance = nullptr; } diff --git a/src/factories/BankFactory.cpp b/src/factories/BankFactory.cpp index 53f4869..7c8c2e8 100644 --- a/src/factories/BankFactory.cpp +++ b/src/factories/BankFactory.cpp @@ -1,5 +1,4 @@ #include "BankFactory.h" -#include "utils/MIODecoder.h" #include "Companion.h" #include "audio/samples_table.h" diff --git a/src/factories/BaseFactory.h b/src/factories/BaseFactory.h index 902b02e..b5e5b65 100644 --- a/src/factories/BaseFactory.h +++ b/src/factories/BaseFactory.h @@ -28,6 +28,33 @@ enum class ExportType { Binary, }; +template<typename T> +std::optional<T> GetNode(YAML::Node& node, const std::string& key) { + if(!node[key]) { + return std::nullopt; + } + + return std::optional<T>(node[key].as<T>()); +} + +template<typename T> +T GetSafeNode(YAML::Node& node, const std::string& key) { + if(!node[key]) { + throw std::runtime_error("Failed to find entry"); + } + + return node[key].as<T>(); +} + +template<typename T> +T GetSafeNode(YAML::Node& node, const std::string& key, const T& def) { + if(!node[key]) { + return def; + } + + return node[key].as<T>(); +} + class IParsedData {}; template<typename T> diff --git a/src/factories/BlobFactory.cpp b/src/factories/BlobFactory.cpp index 886a206..cd644bf 100644 --- a/src/factories/BlobFactory.cpp +++ b/src/factories/BlobFactory.cpp @@ -1,5 +1,5 @@ #include "BlobFactory.h" -#include "utils/MIODecoder.h" +#include "utils/Decompressor.h" #include <iomanip> void BlobCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { @@ -26,18 +26,8 @@ void BlobBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData writer.Finish(write); } -std::optional<std::shared_ptr<IParsedData>> BlobFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& data) { - auto size = data["size"].as<uint32_t>(); - auto offset = data["offset"].as<uint32_t>(); - std::shared_ptr<RawBuffer> result; - - if(data["mio0"]){ - auto decoded = MIO0Decoder::Decode(buffer, offset); - auto cursor = data["mio0"].as<uint32_t>(); - result = std::make_shared<RawBuffer>(decoded.data() + cursor, size); - } else { - result = std::make_shared<RawBuffer>(buffer.data() + offset, size); - } - - return result; +std::optional<std::shared_ptr<IParsedData>> BlobFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { + auto size = GetSafeNode<size_t>(node, "size"); + auto [_, segment] = Decompressor::AutoDecode(node, buffer); + return std::make_shared<RawBuffer>(segment.data, segment.size); }
\ No newline at end of file diff --git a/src/factories/DisplayListFactory.cpp b/src/factories/DisplayListFactory.cpp index 2481d46..ccb7199 100644 --- a/src/factories/DisplayListFactory.cpp +++ b/src/factories/DisplayListFactory.cpp @@ -1,6 +1,6 @@ #include "DisplayListFactory.h" #include "DisplayListOverrides.h" -#include "utils/MIODecoder.h" +#include "utils/Decompressor.h" #include "spdlog/spdlog.h" #include "Companion.h" #include <gfxd.h> @@ -64,7 +64,7 @@ void GFXDSetGBIVersion(){ } void DListHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { - const auto symbol = node["symbol"] ? node["symbol"].as<std::string>() : entryName; + const auto symbol = GetSafeNode(node, "symbol", entryName); if(Companion::Instance->IsOTRMode()){ write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n"; @@ -76,8 +76,9 @@ void DListHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedDat void DListCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { const auto cmds = std::static_pointer_cast<DListData>(raw)->mGfxs; - const auto symbol = node["symbol"].as<std::string>(); - const auto offset = node["offset"].as<uint32_t>(); + const auto symbol = GetSafeNode(node, "symbol", entryName); + const auto offset = GetSafeNode<uint32_t>(node, "offset"); + char out[0xFFFF] = {0}; gfxd_input_buffer(cmds.data(), sizeof(uint32_t) * cmds.size()); @@ -163,11 +164,12 @@ void DListBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedDat if(opcode == GBI(G_VTX)) { auto nvtx = (C0(0, 16)) / sizeof(Vtx); auto didx = C0(16, 4); - uint32_t ptr = SEGMENT_OFFSET(w1); + auto ptr = Decompressor::TranslateAddr(w1); + auto dec = Companion::Instance->GetNodeByAddr(ptr); - if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); decl.has_value()){ - uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); - SPDLOG_INFO("Found vtx: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(decl.value())); + if(dec.has_value()){ + uint64_t hash = CRC64(std::get<0>(dec.value()).c_str()); + SPDLOG_INFO("Found vtx: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value())); // TODO: Find a better way to do this because its going to break on other games Gfx value = gsSPVertexOTR(didx, nvtx, 0); @@ -188,7 +190,7 @@ void DListBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedDat } if(opcode == GBI(G_DL)) { - auto ptr = SEGMENT_OFFSET(w1); + auto ptr = Decompressor::TranslateAddr(w1); auto dec = Companion::Instance->GetNodeByAddr(ptr); Gfx value = gsSPDisplayListOTRHash(ptr); @@ -209,8 +211,7 @@ void DListBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedDat } if(opcode == GBI(G_MOVEMEM)) { - uint32_t ptr = SEGMENT_OFFSET(w1); - + auto ptr = Decompressor::TranslateAddr(w1); auto dec = Companion::Instance->GetNodeByAddr(ptr); w0 &= 0x00FFFFFF; @@ -231,7 +232,7 @@ void DListBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedDat } if(opcode == GBI(G_SETTIMG)) { - auto ptr = SEGMENT_OFFSET(w1); + auto ptr = Decompressor::TranslateAddr(w1); auto dec = Companion::Instance->GetNodeByAddr(ptr); Gfx value = gsDPSetTextureOTRImage(C0(21, 3), C0(19, 2), C0(0, 10), ptr); @@ -261,32 +262,11 @@ void DListBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedDat std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint8_t>& raw_buffer, YAML::Node& node) { const auto gbi = Companion::Instance->GetGBIVersion(); - auto offset = node["offset"].as<uint32_t>(); - const bool isCompressed = node["mio0"] ? true : false; - - std::vector<uint8_t> buffer; - - if(IS_SEGMENTED(offset)){ - const auto segment = Companion::Instance->GetSegmentedAddr(SEGMENT_NUMBER(offset)); - - if(!segment.has_value()) { - SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(offset)); - return std::nullopt; - } - - offset = segment.value() + SEGMENT_OFFSET(offset); - } - - if(isCompressed){ - const auto mio0 = node["mio0"].as<uint32_t>(); - buffer = MIO0Decoder::Decode(raw_buffer, mio0); - } else { - buffer = raw_buffer; - } - - LUS::BinaryReader reader(buffer.data(), buffer.size()); + auto [_, segment] = Decompressor::AutoDecode(node, raw_buffer); + LUS::BinaryReader reader(segment.data, segment.size); reader.SetEndianness(LUS::Endianness::Big); - reader.Seek(offset, LUS::SeekOffsetType::Start); + // Validate this + // reader.Seek(offset, LUS::SeekOffsetType::Start); std::vector<uint32_t> gfxs; auto processing = true; @@ -304,24 +284,8 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint if(opcode == GBI(G_DL)) { std::optional<uint32_t> segment; - uint32_t ptr; - - if(IS_SEGMENTED(w1)){ - segment = Companion::Instance->GetSegmentedAddr(SEGMENT_NUMBER(w1)); - - if(!segment.has_value()) { - SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(w1)); - continue; - } - - ptr = SEGMENT_OFFSET(w1); - } else { - ptr = w1; - } - - auto dec = Companion::Instance->GetNodeByAddr(w1); - if(!dec.has_value()){ + if(const auto decl = Companion::Instance->GetNodeByAddr(w1); !decl.has_value()){ SPDLOG_INFO("Addr to Display list command at 0x{:X} not in yaml, autogenerating it", w1); auto rom = Companion::Instance->GetRomData(); @@ -329,22 +293,17 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint std::string output; YAML::Node dl; + uint32_t ptr = Decompressor::TranslateAddr(w1); - if(isCompressed){ - dl["mio0"] = segment.has_value() ? segment.value() : ptr; - if(segment.has_value()) { - SPDLOG_INFO("Found compressed and segmented display list at 0x{:X}", ptr); - output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_dl_" + Torch::to_hex(segment.value() + w1, false)); - } else { - SPDLOG_INFO("Found compressed display list at 0x{:X}", ptr); - output = Companion::Instance->NormalizeAsset("dl_" + Torch::to_hex(w1, false)); - } + if(Decompressor::IsSegmented(w1)){ + SPDLOG_INFO("Found segmented display list at 0x{:X}", w1); + output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_dl_" + Torch::to_hex(ptr, false)); } else { SPDLOG_INFO("Found display list at 0x{:X}", ptr); output = Companion::Instance->NormalizeAsset("dl_" + Torch::to_hex(w1, false)); } - + Decompressor::CopyCompression(node, dl); dl["type"] = "GFX"; dl["offset"] = ptr; dl["symbol"] = output; @@ -357,14 +316,13 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint Companion::Instance->RegisterAsset(output, dl); } else { - SPDLOG_WARN("Warning: Could not find display list at 0x{:X}", ptr); + SPDLOG_WARN("Warning: Could not find display list at 0x{:X}", w1); } } if(opcode == GBI(G_MOVEMEM)) { uint8_t index = 0; uint8_t offset = 0; - uint32_t ptr = SEGMENT_OFFSET(w1); switch (Companion::Instance->GetGBIVersion()) { case GBIVersion::f3d: @@ -385,26 +343,33 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint } } - - if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); !decl.has_value()){ + if(const auto decl = Companion::Instance->GetNodeByAddr(w1); !decl.has_value()){ SPDLOG_INFO("Addr to Lights1 command at 0x{:X} not in yaml, autogenerating it", w1); - auto addr = Companion::Instance->GetSegmentedAddr(SEGMENT_NUMBER(w1)); - if(!addr.has_value()) { - SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(w1)); - continue; - } auto rom = Companion::Instance->GetRomData(); auto factory = Companion::Instance->GetFactory("LIGHTS")->get(); - std::string output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_lights1_" + Torch::to_hex(addr.value() + w1, false)); + + std::string output; YAML::Node light; + uint32_t ptr = Decompressor::TranslateAddr(w1); + + if(Decompressor::IsSegmented(w1)){ + SPDLOG_INFO("Found segmented lights at 0x{:X}", w1); + output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_lights1_" + Torch::to_hex(ptr, false)); + } else { + SPDLOG_INFO("Found lights at 0x{:X}", ptr); + output = Companion::Instance->NormalizeAsset("lights1_" + Torch::to_hex(w1, false)); + } + + Decompressor::CopyCompression(node, light); light["type"] = "lights"; - light["mio0"] = addr.value(); light["offset"] = ptr; light["symbol"] = output; auto result = factory->parse(rom, light); if(result.has_value()){ Companion::Instance->RegisterAsset(output, light); } + } else { + SPDLOG_WARN("Warning: Could not find lights at 0x{:X}", w1); } } @@ -424,50 +389,25 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint break; } - std::optional<uint32_t> segment; - uint32_t ptr; - - if(IS_SEGMENTED(w1)){ - segment = Companion::Instance->GetSegmentedAddr(SEGMENT_NUMBER(w1)); - - if(!segment.has_value()) { - SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(w1)); - continue; - } - - ptr = SEGMENT_OFFSET(w1); - } else { - ptr = w1; - } - - if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); !decl.has_value()){ - SPDLOG_INFO("Addr to Vtx array at 0x{:X} not in yaml, autogenerating it", w1); - auto addr = Companion::Instance->GetSegmentedAddr(SEGMENT_NUMBER(w1)); - if(!addr.has_value()) { - SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(w1)); - break; - } + if(const auto decl = Companion::Instance->GetNodeByAddr(w1); !decl.has_value()){ + SPDLOG_INFO("Addr to Vtx array at 0x{:X} not in yaml, autogenerating it", w1); + auto ptr = Decompressor::TranslateAddr(w1); auto rom = Companion::Instance->GetRomData(); auto factory = Companion::Instance->GetFactory("VTX")->get(); std::string output; YAML::Node vtx; - if(isCompressed){ - vtx["mio0"] = segment.has_value() ? segment.value() : ptr; - if(segment.has_value()) { - SPDLOG_INFO("Found compressed and segmented display list at 0x{:X}", ptr); - output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_vtx_" + Torch::to_hex(segment.value() + w1, false)); - } else { - SPDLOG_INFO("Found compressed display list at 0x{:X}", ptr); - output = Companion::Instance->NormalizeAsset("vtx_" + Torch::to_hex(w1, false)); - } + if(Decompressor::IsSegmented(w1)){ + SPDLOG_INFO("Found segmented vtx at 0x{:X}", ptr); + output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_vtx_" + Torch::to_hex(ptr, false)); } else { - SPDLOG_INFO("Found display list at 0x{:X}", ptr); - output = Companion::Instance->NormalizeAsset("dl_" + Torch::to_hex(w1, false)); + SPDLOG_INFO("Found vtx at 0x{:X}", ptr); + output = Companion::Instance->NormalizeAsset("vtx_" + Torch::to_hex(w1, false)); } + Decompressor::CopyCompression(node, vtx); vtx["type"] = "VTX"; vtx["offset"] = ptr; vtx["count"] = nvtx; @@ -476,6 +416,8 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint if(result.has_value()){ Companion::Instance->RegisterAsset(output, vtx); } + } else { + SPDLOG_WARN("Warning: Could not find vtx at 0x{:X}", w1); } } diff --git a/src/factories/DisplayListOverrides.cpp b/src/factories/DisplayListOverrides.cpp index 7da6ecf..cdfaba0 100644 --- a/src/factories/DisplayListOverrides.cpp +++ b/src/factories/DisplayListOverrides.cpp @@ -14,7 +14,7 @@ void Triangle2(const Gfx* gfx) { auto w1 = gfx->words.w1; auto v1 = std::to_string( ((w0 >> 16) & 0xFF) / 2 ); - auto v2 = std::to_string( ((w0 >> 8) & 0xFF) / 2 ); + auto v2 = std::to_string( ((w0 >> 8) & 0xFF) / 2 ); auto v3 = std::to_string( (w0 & 0xFF) / 2 ); auto v4 = std::to_string( ((w1 >> 16) & 0xFF) / 2 ); @@ -49,7 +49,7 @@ int Vtx(uint32_t vtx, int32_t num) { uint32_t ptr = SEGMENT_OFFSET(vtx); if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); decl.has_value()){ auto node = std::get<1>(decl.value()); - auto symbol = node["symbol"].as<std::string>(); + auto symbol = GetSafeNode<std::string>(node, "symbol"); SPDLOG_INFO("Wrote vtx: 0x{:X} Symbol: {}", ptr, symbol); gfxd_puts(symbol.c_str()); return 1; @@ -63,7 +63,7 @@ int Texture(uint32_t timg, int32_t fmt, int32_t siz, int32_t width, int32_t heig uint32_t ptr = SEGMENT_OFFSET(timg); if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); decl.has_value()){ auto node = std::get<1>(decl.value()); - auto symbol = node["symbol"].as<std::string>(); + auto symbol = GetSafeNode<std::string>(node, "symbol"); SPDLOG_INFO("Wrote texture: 0x{:X} Symbol: {}", ptr, symbol); gfxd_puts(symbol.c_str()); return 1; @@ -77,7 +77,7 @@ int Light(uint32_t lightsn, int32_t count) { uint32_t ptr = SEGMENT_OFFSET(lightsn); if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); decl.has_value()){ auto node = std::get<1>(decl.value()); - auto symbol = node["symbol"].as<std::string>(); + auto symbol = GetSafeNode<std::string>(node, "symbol"); SPDLOG_INFO("Wrote light: 0x{:X} Symbol: {}", ptr, symbol); gfxd_puts(symbol.c_str()); return 1; @@ -91,7 +91,7 @@ int DisplayList(uint32_t dl) { uint32_t ptr = SEGMENT_OFFSET(dl); if(const auto decl = Companion::Instance->GetNodeByAddr(ptr); decl.has_value()){ auto node = std::get<1>(decl.value()); - auto symbol = node["symbol"].as<std::string>(); + auto symbol = GetSafeNode<std::string>(node, "symbol"); SPDLOG_INFO("Wrote display list: 0x{:X} Symbol: {}", ptr, symbol); gfxd_puts(symbol.c_str()); return 1; diff --git a/src/factories/LightsFactory.cpp b/src/factories/LightsFactory.cpp index bcabbe8..0e8265c 100644 --- a/src/factories/LightsFactory.cpp +++ b/src/factories/LightsFactory.cpp @@ -1,11 +1,11 @@ #include "LightsFactory.h" -#include "utils/MIODecoder.h" +#include "utils/Decompressor.h" #include "spdlog/spdlog.h" #include "Companion.h" void LightsHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { - const auto symbol = node["symbol"] ? node["symbol"].as<std::string>() : entryName; + const auto symbol = GetSafeNode(node, "symbol", entryName); if(Companion::Instance->IsOTRMode()){ write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n"; @@ -17,7 +17,7 @@ void LightsHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedDa void LightsCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto light = std::static_pointer_cast<LightsData>(raw)->mLights; - auto symbol = node["symbol"].as<std::string>(); + auto symbol = GetSafeNode(node, "symbol", entryName); write << "Lights1 " << symbol << " = gdSPDefLights1 (\n"; @@ -68,11 +68,9 @@ void LightsBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedDa } std::optional<std::shared_ptr<IParsedData>> LightsFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { - auto mio0 = node["mio0"].as<size_t>(); - auto offset = node["offset"].as<uint32_t>(); - - auto decoded = MIO0Decoder::Decode(buffer, offset); - LUS::BinaryReader reader(decoded.data() + mio0, sizeof(Lights1Raw)); + auto decoded = Decompressor::AutoDecode(node, buffer); + auto [_, segment] = Decompressor::AutoDecode(node, buffer); + LUS::BinaryReader reader(segment.data, sizeof(Lights1Raw)); reader.SetEndianness(LUS::Endianness::Big); Lights1Raw lights; @@ -90,7 +88,6 @@ std::optional<std::shared_ptr<IParsedData>> LightsFactory::parse(std::vector<uin auto g2 = reader.ReadUByte(); auto b2 = reader.ReadUByte(); - reader.Seek(5, LUS::SeekOffsetType::Current); // Direction @@ -98,6 +95,7 @@ std::optional<std::shared_ptr<IParsedData>> LightsFactory::parse(std::vector<uin auto y = reader.ReadInt8(); auto z = reader.ReadInt8(); + // TODO: This is a hack, but it works for now. // The struct has several copies/padding. The zeros skip those for gdSPDefLights1. lights = {r, g, b, 0, 0, 0, 0, 0, r2, g2, b2, 0, 0, 0, 0, 0, x, y, z}; diff --git a/src/factories/SampleFactory.cpp b/src/factories/SampleFactory.cpp index 100c7da..f367a1e 100644 --- a/src/factories/SampleFactory.cpp +++ b/src/factories/SampleFactory.cpp @@ -1,5 +1,4 @@ #include "SampleFactory.h" -#include "utils/MIODecoder.h" void SampleBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto writer = LUS::BinaryWriter(); diff --git a/src/factories/SequenceFactory.cpp b/src/factories/SequenceFactory.cpp index 46ed35e..17b1ac6 100644 --- a/src/factories/SequenceFactory.cpp +++ b/src/factories/SequenceFactory.cpp @@ -1,25 +1,24 @@ #include "SequenceFactory.h" -#include "utils/MIODecoder.h" void SequenceBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto writer = LUS::BinaryWriter(); - auto sequence = std::static_pointer_cast<SequenceData>(raw); + const auto sequence = std::static_pointer_cast<SequenceData>(raw); WriteHeader(writer, LUS::ResourceType::Sequence, 0); - writer.Write((uint32_t) sequence->mId); - writer.Write((uint32_t) sequence->mBanks.size()); + writer.Write(sequence->mId); + writer.Write(static_cast<uint32_t>(sequence->mBanks.size())); for (auto& bank : sequence->mBanks) { writer.Write(bank); } - writer.Write((uint32_t) sequence->mSize); - writer.Write((char*) sequence->mBuffer.data(), sequence->mSize); + writer.Write( sequence->mSize); + writer.Write(reinterpret_cast<char*>(sequence->mBuffer.data()), sequence->mSize); writer.Finish(write); } std::optional<std::shared_ptr<IParsedData>> SequenceFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& data) { auto id = data["id"].as<uint32_t>(); auto size = data["size"].as<size_t>(); - auto offset = data["offset"].as<size_t>(); + const auto offset = data["offset"].as<size_t>(); auto banks = data["banks"].as<std::vector<std::string>>(); return std::make_shared<SequenceData>(id, size, buffer.data() + offset, banks); }
\ No newline at end of file diff --git a/src/factories/TextureFactory.cpp b/src/factories/TextureFactory.cpp index 3759737..c08c26c 100644 --- a/src/factories/TextureFactory.cpp +++ b/src/factories/TextureFactory.cpp @@ -1,5 +1,5 @@ #include "TextureFactory.h" -#include "utils/MIODecoder.h" +#include "utils/Decompressor.h" #include "spdlog/spdlog.h" #include "Companion.h" #include <iomanip> @@ -45,7 +45,7 @@ std::vector<uint8_t> alloc_ia8_text_from_i1(uint16_t *in, int16_t width, int16_t } void TextureHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { - auto symbol = node["symbol"] ? node["symbol"].as<std::string>() : entryName; + auto symbol = GetSafeNode(node, "symbol", entryName); auto data = std::static_pointer_cast<TextureData>(raw)->mBuffer; if(Companion::Instance->IsOTRMode()){ @@ -58,8 +58,8 @@ void TextureHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedD void TextureCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { auto data = std::static_pointer_cast<TextureData>(raw)->mBuffer; - auto symbol = node["symbol"] ? node["symbol"].as<std::string>() : entryName; - auto format = node["format"].as<std::string>(); + auto symbol = GetSafeNode(node, "symbol", entryName); + auto format = GetSafeNode<std::string>(node, "format"); std::transform(format.begin(), format.end(), format.begin(), tolower); (*replacement) += "." + format; @@ -107,11 +107,11 @@ void TextureBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedD } std::optional<std::shared_ptr<IParsedData>> TextureFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { - auto format = node["format"].as<std::string>(); - auto width = node["width"].as<uint32_t>(); - auto height = node["height"].as<uint32_t>(); - auto size = node["size"].as<size_t>(); - auto offset = node["offset"].as<size_t>(); + auto format = GetSafeNode<std::string>(node, "format"); + auto width = GetSafeNode<uint32_t>(node, "width"); + auto height = GetSafeNode<uint32_t>(node, "height"); + auto size = GetSafeNode<uint32_t>(node, "size"); + auto offset = GetSafeNode<uint32_t>(node, "offset"); if (format.empty()) { SPDLOG_ERROR("Texture entry at {:X} in yaml missing format node\n\ @@ -126,26 +126,18 @@ std::optional<std::shared_ptr<IParsedData>> TextureFactory::parse(std::vector<ui TextureType type = gTextureTypes.at(format); + auto [_, segment] = Decompressor::AutoDecode(node, buffer); std::vector<uint8_t> result; - if(node["mio0"]){ - auto decoded = MIO0Decoder::Decode(buffer, offset); - auto mio0 = node["mio0"].as<size_t>(); - auto data = decoded.data() + mio0; - - if(type == TextureType::GrayscaleAlpha1bpp){ - result = alloc_ia8_text_from_i1((uint16_t*) data, 8, 16); - } else { - result = std::vector(data, data + size); - } - - } else { - result = std::vector(buffer.data() + offset, buffer.data() + offset + size); - } + if(type == TextureType::GrayscaleAlpha1bpp){ + result = alloc_ia8_text_from_i1((uint16_t*) segment.data, 8, 16); + } else { + result = std::vector(segment.data, segment.data + segment.size); + } SPDLOG_INFO("Texture: {} {}x{} {}", format, width, height, size); SPDLOG_INFO("Offset: {}", offset); - SPDLOG_INFO("Has MIO0: {}", node["mio0"] ? "true" : "false"); + SPDLOG_INFO("Has MIO0: {}", Decompressor::IsCompressed(node) ? "true" : "false"); SPDLOG_INFO("Size: {}", result.size()); if(result.size() == 0){ diff --git a/src/factories/VtxFactory.cpp b/src/factories/VtxFactory.cpp index e5214c5..e3ec716 100644 --- a/src/factories/VtxFactory.cpp +++ b/src/factories/VtxFactory.cpp @@ -1,13 +1,13 @@ #include "VtxFactory.h" #include "Companion.h" -#include "utils/MIODecoder.h" +#include "utils/Decompressor.h" #define NUM(x) std::dec << std::setfill(' ') << std::setw(6) << x #define COL(c) "0x" << std::hex << std::setw(2) << std::setfill('0') << c void VtxHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { - const auto symbol = node["symbol"] ? node["symbol"].as<std::string>() : entryName; + const auto symbol = GetSafeNode(node, "symbol", entryName); if(Companion::Instance->IsOTRMode()){ write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n"; @@ -19,8 +19,8 @@ void VtxHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> void VtxCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto vtx = std::static_pointer_cast<VtxData>(raw)->mVtxs; - const auto symbol = node["symbol"].as<std::string>(); - const auto offset = node["offset"].as<uint32_t>(); + const auto symbol = GetSafeNode(node, "symbol", entryName); + const auto offset = GetSafeNode<uint32_t>(node, "offset"); if (Companion::Instance->IsDebug()) { write << "// 0x" << std::hex << std::uppercase << offset << "\n"; @@ -83,12 +83,10 @@ void VtxBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> } std::optional<std::shared_ptr<IParsedData>> VtxFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { - auto mio0 = node["mio0"].as<size_t>(); - auto offset = node["offset"].as<uint32_t>(); - auto count = node["count"].as<size_t>(); + auto count = GetSafeNode<size_t>(node, "count"); - auto decoded = MIO0Decoder::Decode(buffer, offset); - LUS::BinaryReader reader(decoded.data() + mio0, count * sizeof(VtxRaw) ); + auto [_, segment] = Decompressor::AutoDecode(node, buffer); + LUS::BinaryReader reader(segment.data, count * sizeof(VtxRaw)); reader.SetEndianness(LUS::Endianness::Big); std::vector<VtxRaw> vertices; diff --git a/src/factories/mk64/WaypointFactory.cpp b/src/factories/mk64/WaypointFactory.cpp index ea84ede..9fdcd12 100644 --- a/src/factories/mk64/WaypointFactory.cpp +++ b/src/factories/mk64/WaypointFactory.cpp @@ -1,13 +1,13 @@ #include "WaypointFactory.h" #include "Companion.h" -#include "utils/MIODecoder.h" +#include "utils/Decompressor.h" #define NUM(x) std::dec << std::setfill(' ') << std::setw(6) << x #define COL(c) "0x" << std::hex << std::setw(2) << std::setfill('0') << c void MK64::WaypointHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { - const auto symbol = node["symbol"] ? node["symbol"].as<std::string>() : entryName; + const auto symbol = GetSafeNode(node, "symbol", entryName); if(Companion::Instance->IsOTRMode()){ write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n"; @@ -19,7 +19,7 @@ void MK64::WaypointHeaderExporter::Export(std::ostream &write, std::shared_ptr<I void MK64::WaypointCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto waypoints = std::static_pointer_cast<WaypointData>(raw)->mWaypoints; - auto symbol = node["symbol"].as<std::string>(); + auto symbol = GetSafeNode(node, "symbol", entryName); write << "TrackWaypoint " << symbol << "[] = {\n"; @@ -58,12 +58,10 @@ void MK64::WaypointBinaryExporter::Export(std::ostream &write, std::shared_ptr<I } std::optional<std::shared_ptr<IParsedData>> MK64::WaypointFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { - auto mio0 = node["mio0"].as<size_t>(); - auto offset = node["offset"].as<uint32_t>(); - auto count = node["count"].as<size_t>(); + auto count = GetSafeNode<size_t>(node, "count"); - auto decoded = MIO0Decoder::Decode(buffer, offset); - LUS::BinaryReader reader(decoded.data() + mio0, count * sizeof(MK64::TrackWaypoint) ); + auto [_, segment] = Decompressor::AutoDecode(node, buffer); + LUS::BinaryReader reader(segment.data, count * sizeof(MK64::TrackWaypoint)); reader.SetEndianness(LUS::Endianness::Big); std::vector<MK64::TrackWaypoint> waypoints; diff --git a/src/factories/sm64/AnimationFactory.cpp b/src/factories/sm64/AnimationFactory.cpp index cdbdedf..368de1f 100644 --- a/src/factories/sm64/AnimationFactory.cpp +++ b/src/factories/sm64/AnimationFactory.cpp @@ -1,10 +1,9 @@ #include "AnimationFactory.h" -#include "utils/MIODecoder.h" #include "spdlog/spdlog.h" void SM64::AnimationBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto writer = LUS::BinaryWriter(); - auto anim = std::static_pointer_cast<AnimationData>(raw); + const auto anim = std::static_pointer_cast<AnimationData>(raw); WriteHeader(writer, LUS::ResourceType::Anim, 0); writer.Write(anim->mFlags); @@ -29,11 +28,11 @@ void SM64::AnimationBinaryExporter::Export(std::ostream &write, std::shared_ptr< } std::optional<std::shared_ptr<IParsedData>> SM64::AnimationFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { - auto headerNode = node["header"]; - auto valuesNode = node["values"]; - auto indexNode = node["indices"]; + auto headerNode = GetSafeNode<YAML::Node>(node, "header"); + auto valuesNode = GetSafeNode<YAML::Node>(node, "values"); + auto indexNode = GetSafeNode<YAML::Node>(node, "indices"); - LUS::BinaryReader header(reinterpret_cast<char *>(buffer.data()) + headerNode["offset"].as<uint32_t>(), headerNode["size"].as<uint32_t>()); + LUS::BinaryReader header(reinterpret_cast<char *>(buffer.data()) + GetSafeNode<uint32_t>(headerNode, "offset"), GetSafeNode<uint32_t>(headerNode, "size")); header.SetEndianness(LUS::Endianness::Big); auto flags = header.ReadInt16(); @@ -46,17 +45,17 @@ std::optional<std::shared_ptr<IParsedData>> SM64::AnimationFactory::parse(std::v header.ReadUInt32(); auto length = header.ReadUInt32(); - LUS::BinaryReader indices(reinterpret_cast<char*>(buffer.data()) + indexNode["offset"].as<uint32_t>(), indexNode["size"].as<uint32_t>()); + LUS::BinaryReader indices(reinterpret_cast<char*>(buffer.data()) + GetSafeNode<uint32_t>(indexNode, "offset"), GetSafeNode<uint32_t>(indexNode, "size")); indices.SetEndianness(LUS::Endianness::Big); - size_t indexLength = indexNode["size"].as<uint32_t>() / sizeof(int16_t); + size_t indexLength = GetSafeNode<uint32_t>(indexNode, "size") / sizeof(int16_t); std::vector<int16_t> indicesData; for (size_t i = 0; i < indexLength; i++) { indicesData.push_back(indices.ReadInt16()); } - LUS::BinaryReader values((char*) buffer.data() + valuesNode["offset"].as<uint32_t>(), valuesNode["size"].as<uint32_t>()); + LUS::BinaryReader values(reinterpret_cast<char*>(buffer.data()) + GetSafeNode<uint32_t>(valuesNode, "offset"), GetSafeNode<uint32_t>(valuesNode, "size")); values.SetEndianness(LUS::Endianness::Big); - size_t entries = valuesNode["size"].as<uint32_t>() / sizeof(uint16_t); + size_t entries = GetSafeNode<uint32_t>(valuesNode, "size") / sizeof(uint16_t); std::vector<uint16_t> valuesData; for (size_t i = 0; i < entries; i++) { valuesData.push_back(values.ReadUInt16()); diff --git a/src/factories/sm64/DialogFactory.cpp b/src/factories/sm64/DialogFactory.cpp index 066b575..8cfdcd0 100644 --- a/src/factories/sm64/DialogFactory.cpp +++ b/src/factories/sm64/DialogFactory.cpp @@ -1,6 +1,6 @@ #include "DialogFactory.h" -#include "utils/MIODecoder.h" #include "spdlog/spdlog.h" +#include "utils/Decompressor.h" void SM64::DialogBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto writer = LUS::BinaryWriter(); @@ -18,14 +18,12 @@ void SM64::DialogBinaryExporter::Export(std::ostream &write, std::shared_ptr<IPa } std::optional<std::shared_ptr<IParsedData>> SM64::DialogFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { - auto offset = node["offset"].as<int32_t>(); - auto mio0 = node["mio0"].as<size_t>(); + auto [root, segment] = Decompressor::AutoDecode(node, buffer); - auto decoded = MIO0Decoder::Decode(buffer, offset); - auto bytes = (uint8_t*) decoded.data(); - LUS::BinaryReader reader(bytes, decoded.size()); + LUS::BinaryReader reader(segment.data, segment.size); reader.SetEndianness(LUS::Endianness::Big); - reader.Seek(mio0, LUS::SeekOffsetType::Start); + // Validate this + // reader.Seek(mio0, LUS::SeekOffsetType::Start); auto unused = reader.ReadUInt32(); auto linesPerBox = reader.ReadUByte(); @@ -38,8 +36,8 @@ std::optional<std::shared_ptr<IParsedData>> SM64::DialogFactory::parse(std::vect auto str = SEGMENT_OFFSET(reader.ReadInt32()); std::vector<uint8_t> text; - while(bytes[str] != 0xFF){ - auto c = bytes[str++]; + while(root->data[str] != 0xFF){ + auto c = root->data[str++]; text.push_back(c); } text.push_back(0xFF); diff --git a/src/factories/sm64/DictionaryFactory.cpp b/src/factories/sm64/DictionaryFactory.cpp index 39d6055..2b723ef 100644 --- a/src/factories/sm64/DictionaryFactory.cpp +++ b/src/factories/sm64/DictionaryFactory.cpp @@ -1,17 +1,16 @@ #include "DictionaryFactory.h" -#include "utils/MIODecoder.h" void SM64::DictionaryBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto writer = LUS::BinaryWriter(); - auto data = std::static_pointer_cast<DictionaryData>(raw); + const auto data = std::static_pointer_cast<DictionaryData>(raw); WriteHeader(writer, LUS::ResourceType::Dictionary, 0); - writer.Write((uint32_t) data->mDictionary.size()); + writer.Write(static_cast<uint32_t>(data->mDictionary.size())); for(auto& [key, value] : data->mDictionary){ writer.Write(key); - writer.Write((uint32_t) value.size()); - writer.Write((char*) value.data(), value.size()); + writer.Write(static_cast<uint32_t>(value.size())); + writer.Write(reinterpret_cast<char*>(value.data()), value.size()); } writer.Finish(write); } @@ -24,7 +23,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::DictionaryFactory::parse(std:: auto offset = it->second.as<size_t>(); std::vector<uint8_t> text; - auto bytes = (uint8_t*) buffer.data(); + const auto bytes = buffer.data(); while(bytes[offset] != 0xFF){ auto c = bytes[offset++]; diff --git a/src/factories/sm64/GeoLayoutFactory.cpp b/src/factories/sm64/GeoLayoutFactory.cpp index 03606bd..520b973 100644 --- a/src/factories/sm64/GeoLayoutFactory.cpp +++ b/src/factories/sm64/GeoLayoutFactory.cpp @@ -1,7 +1,6 @@ #include "GeoLayoutFactory.h" #include "spdlog/spdlog.h" -#include "utils/MIODecoder.h" #include "geo/GeoCommand.h" #include "Companion.h" #include "geo/GeoUtils.h" @@ -193,7 +192,7 @@ void SM64::GeoHeaderExporter::Export(std::ostream&write, std::shared_ptr<IParsed } std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { - const size_t offset = Torch::translate(node["offset"].as<uint32_t>()); + const size_t offset = Torch::translate(GetSafeNode<uint32_t>(node, "offset")); auto cmd = buffer.data() + offset; bool processing = true; std::vector<GeoCommand> commands; diff --git a/src/factories/sm64/Original.old b/src/factories/sm64/Original.old deleted file mode 100644 index 9f59aa4..0000000 --- a/src/factories/sm64/Original.old +++ /dev/null @@ -1,485 +0,0 @@ - -int current_tab_size = 0; - -static inline void print_cmd(GeoCommand cmd, std::string c){ - if(cmd == GeoCommand::CLOSE_NODE){ - current_tab_size--; - } - - for(int i = 0; i < current_tab_size; i++){ - std::cout << "\t"; - } - - if(cmd == GeoCommand::OPEN_NODE){ - current_tab_size++; - } - - std::cout << "GEO_" << c << "()" << std::endl; -} - -typedef uint32_t GeoLayout; - - auto offset = data["offset"].as<size_t>(); - auto cmd = (uint8_t*) buffer.data() + offset; - auto processing = true; - - std::vector<GeoLayout> layout; - auto geo_writer = new LUS::BinaryWriter(); - -// #define GeoWrite(x) layout.insert(layout.end(), {x}) -// -// while(processing){ -// auto opcode = cmd[0x00]; -// switch (opcode) { -// case CMD_INFO(BRANCH_AND_LINK) { -// geo_writer->Write((uint8_t) BRANCH_AND_LINK_OTR); -// uint32_t ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x04))); -// auto decl = Companion::Instance->GetNodeByAddr(ptr); -// -// if(decl.has_value()){ -// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); -// SPDLOG_INFO("Found geo: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(decl.value())); -// geo_writer->Write(hash); -// } else { -// SPDLOG_INFO("Warning: Could not find geo at 0x{:X}", ptr); -// geo_writer->Write((uint64_t) 0); -// } -// -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(BRANCH) { -// geo_writer->Write((uint8_t) BRANCH_OTR); -// geo_writer->Write(cur_geo_cmd_u8(0x01)); -// -// int32_t ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x04))); -// auto decl = Companion::Instance->GetNodeByAddr(ptr); -// -// if(decl.has_value()){ -// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); -// SPDLOG_INFO("Found geo: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(decl.value())); -// geo_writer->Write(hash); -// } else { -// SPDLOG_INFO("Warning: Could not find geo at 0x{:X}", ptr); -// geo_writer->Write((uint64_t) 0); -// } -// -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(END) -// geo_writer->Write((uint8_t) END); -// processing = false; -// break; -// case CMD_INFO(RETURN) -// geo_writer->Write((uint8_t) RETURN); -// processing = false; -// break; -// case CMD_NOP(OPEN_NODE) -// case CMD_NOP(CLOSE_NODE) -// case CMD_INFO(ASSIGN_AS_VIEW) { -// geo_writer->Write(ASSIGN_AS_VIEW); -// geo_writer->Write(cur_geo_cmd_s16(0x02)); -// break; -// } -// case CMD_INFO(UPDATE_NODE_FLAGS) { -// geo_writer->Write((uint8_t) UPDATE_NODE_FLAGS); -// geo_writer->Write(cur_geo_cmd_u8(0x01)); -// geo_writer->Write(cur_geo_cmd_s16(0x02)); -// break; -// } -// case CMD_INFO(NODE_ROOT) { -// auto a1 = cur_geo_cmd_s16(0x02); -// auto a2 = cur_geo_cmd_s16(0x04); -// auto a3 = cur_geo_cmd_s16(0x06); -// auto a4 = cur_geo_cmd_s16(0x08); -// auto a5 = cur_geo_cmd_s16(0x0A); -// GeoWrite(GEO_NODE_SCREEN_AREA(a1, a2, a3, a4, a5)); -// cmd += 0x0C << CMD_SIZE_SHIFT; -// processing = false; -// } -// case CMD_INFO(NODE_ORTHO_PROJECTION) { -// geo_writer->Write((uint8_t) NODE_ORTHO_PROJECTION); -// geo_writer->Write(cur_geo_cmd_s16(0x02)); -// cmd += 0x04 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_PERSPECTIVE) { -// geo_writer->Write((uint8_t) NODE_PERSPECTIVE); -// auto param = cur_geo_cmd_u8(0x01); -// auto fov = cur_geo_cmd_s16(0x02); -// auto near = cur_geo_cmd_s16(0x04); -// auto far = cur_geo_cmd_s16(0x06); -// -// geo_writer->Write(param); -// geo_writer->Write(fov); -// geo_writer->Write(near); -// geo_writer->Write(far); -// -// if (param != 0) { -// auto func = cur_geo_cmd_u32(0x08); -// geo_writer->Write(func); -// cmd += 4 << CMD_SIZE_SHIFT; -// } -// -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_NOP(NODE_START) -// case CMD_INFO(NODE_MASTER_LIST) { -// geo_writer->Write((uint8_t) NODE_MASTER_LIST); -// geo_writer->Write(cur_geo_cmd_u8(0x01)); -// cmd += 0x04 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_LEVEL_OF_DETAIL) { -// geo_writer->Write((uint8_t) NODE_LEVEL_OF_DETAIL); -// int16_t minDistance = cur_geo_cmd_s16(0x04); -// int16_t maxDistance = cur_geo_cmd_s16(0x06); -// -// geo_writer->Write(minDistance); -// geo_writer->Write(maxDistance); -// -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_SWITCH_CASE) { -// geo_writer->Write((uint8_t) NODE_SWITCH_CASE_OTR); -// auto cs = cur_geo_cmd_s16(0x02); -// auto ptr = cur_geo_cmd_u32(0x04); -// -// geo_writer->Write(cs); -// geo_writer->Write(ptr); -// -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_CAMERA) { -// geo_writer->Write((uint8_t) NODE_CAMERA_OTR); -// auto cmd_pos = (int16_t *) &cmd[4]; -// auto mode = cur_geo_cmd_s16(0x02); -// -// geo_writer->Write(mode); -// -// Vec3f pos, focus; -// -// cmd_pos = read_vec3s_to_vec3f(pos, cmd_pos); -// read_vec3s_to_vec3f(focus, cmd_pos); -// -// geo_writer->Write(pos[0]); -// geo_writer->Write(pos[1]); -// geo_writer->Write(pos[2]); -// geo_writer->Write(focus[0]); -// geo_writer->Write(focus[1]); -// geo_writer->Write(focus[2]); -// -// auto ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x10))); -// geo_writer->Write(ptr); -// -// cmd += 0x14 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_TRANSLATION_ROTATION) { -// geo_writer->Write(NODE_TRANSLATION_ROTATION_OTR); -// auto params = cur_geo_cmd_u8(0x01); -// auto cmd_pos = (int16_t*) cmd; -// -// Vec3s translation, rotation; -// -// geo_writer->Write(params); -// -// switch ((params & 0x70) >> 4) { -// case 0: -// cmd_pos = read_vec3s(translation, &cmd_pos[2]); -// geo_writer->Write(translation[0]); -// geo_writer->Write(translation[1]); -// geo_writer->Write(translation[2]); -// cmd_pos = read_vec3s_angle(rotation, cmd_pos); -// geo_writer->Write(rotation[0]); -// geo_writer->Write(rotation[1]); -// geo_writer->Write(rotation[2]); -// break; -// case 1: -// cmd_pos = read_vec3s(translation, &cmd_pos[1]); -// geo_writer->Write(translation[0]); -// geo_writer->Write(translation[1]); -// geo_writer->Write(translation[2]); -// break; -// case 2: -// cmd_pos = read_vec3s_angle(rotation, &cmd_pos[1]); -// geo_writer->Write(rotation[0]); -// geo_writer->Write(rotation[1]); -// geo_writer->Write(rotation[2]); -// break; -// case 3: -// cmd_pos += 2 << CMD_SIZE_SHIFT; -// break; -// } -// -// if (params & 0x80) { -// auto dlist = SEGMENT_OFFSET(BSWAP32(*(uint32_t*) &cmd_pos[0])); -// auto decl = Companion::Instance->GetNodeByAddr(dlist); -// if(decl.has_value()){ -// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); -// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value())); -// geo_writer->Write(hash); -// } else { -// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist); -// geo_writer->Write((uint64_t) 0); -// } -// cmd_pos += 2 << CMD_SIZE_SHIFT; -// } -// -// cmd = (uint8_t*) cmd_pos; -// break; -// } -// case CMD_INFO(NODE_TRANSLATION) { -// geo_writer->Write(NODE_TRANSLATION_OTR); -// auto params = cur_geo_cmd_u8(0x01); -// auto cmd_pos = (int16_t*) cmd; -// -// Vec3s translation; -// cmd_pos = read_vec3s(translation, &cmd_pos[1]); -// -// geo_writer->Write(translation[0]); -// geo_writer->Write(translation[1]); -// geo_writer->Write(translation[2]); -// -// if (params & 0x80) { -// auto dlist = SEGMENT_OFFSET(BSWAP32(*(uint32_t*) &cmd_pos[0])); -// auto decl = Companion::Instance->GetNodeByAddr(dlist); -// if(decl.has_value()){ -// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); -// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value())); -// geo_writer->Write(hash); -// } else { -// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist); -// geo_writer->Write((uint64_t) 0); -// } -// cmd_pos += 2 << CMD_SIZE_SHIFT; -// } -// -// cmd = (uint8_t*) cmd_pos; -// break; -// } -// case CMD_INFO(NODE_ROTATION) { -// geo_writer->Write(NODE_ROTATION_OTR); -// auto params = cur_geo_cmd_u8(0x01); -// auto cmd_pos = (int16_t*) cmd; -// -// Vec3s sp2c; -// cmd_pos = read_vec3s(sp2c, &cmd_pos[1]); -// -// geo_writer->Write(sp2c[0]); -// geo_writer->Write(sp2c[1]); -// geo_writer->Write(sp2c[2]); -// -// if (params & 0x80) { -// auto dlist = SEGMENT_OFFSET(BSWAP32(*(uint32_t*) &cmd_pos[0])); -// auto decl = Companion::Instance->GetNodeByAddr(dlist); -// if(decl.has_value()){ -// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); -// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value())); -// geo_writer->Write(hash); -// } else { -// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist); -// geo_writer->Write((uint64_t) 0); -// } -// cmd_pos += 2 << CMD_SIZE_SHIFT; -// } -// -// cmd = (uint8_t*) cmd_pos; -// break; -// } -// case CMD_INFO(NODE_ANIMATED_PART) { -// geo_writer->Write(NODE_ANIMATED_PART_OTR); -// -// auto layer = cur_geo_cmd_u8(0x01); -// auto ptr = cur_geo_cmd_u32(0x08); -// -// geo_writer->Write(layer); -// geo_writer->Write(ptr); -// -// auto dlist = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x08))); -// auto decl = Companion::Instance->GetNodeByAddr(dlist); -// if(decl.has_value()){ -// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); -// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value())); -// geo_writer->Write(hash); -// } else { -// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist); -// geo_writer->Write((uint64_t) 0); -// } -// -// cmd += 0x0C << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_BILLBOARD) { -// geo_writer->Write(NODE_BILLBOARD_OTR); -// -// Vec3s translation; -// auto params = cur_geo_cmd_u8(0x01); -// auto cmd_pos = (int16_t*) cmd; -// -// cmd_pos = read_vec3s(translation, &cmd_pos[1]); -// geo_writer->Write(params); -// if (params & 0x80) { -// auto dlist = SEGMENT_OFFSET(BSWAP32(*(uint32_t*) &cmd_pos[0])); -// auto decl = Companion::Instance->GetNodeByAddr(dlist); -// if (decl.has_value()) { -// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); -// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, -// std::get<0>(decl.value())); -// geo_writer->Write(hash); -// } else { -// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist); -// geo_writer->Write((uint64_t) 0); -// } -// -// cmd_pos += 2 << CMD_SIZE_SHIFT; -// } -// -// cmd = (uint8_t*) cmd_pos; -// break; -// } -// case CMD_INFO(NODE_DISPLAY_LIST) { -// geo_writer->Write((uint8_t) NODE_DISPLAY_LIST_OTR); -// -// int32_t layer = cur_geo_cmd_u8(0x01); -// auto ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x04))); -// -// geo_writer->Write(layer); -// -// auto decl = Companion::Instance->GetNodeByAddr(ptr); -// -// if(decl.has_value()){ -// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); -// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(decl.value())); -// geo_writer->Write(hash); -// } else { -// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", ptr); -// geo_writer->Write((uint64_t) 0); -// } -// -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_SHADOW) { -// geo_writer->Write((uint8_t) NODE_SHADOW); -// auto type = cur_geo_cmd_s16(0x02); -// auto solidity = cur_geo_cmd_s16(0x04); -// auto scale = cur_geo_cmd_s16(0x06); -// -// geo_writer->Write(type); -// geo_writer->Write(solidity); -// geo_writer->Write(scale); -// -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_NOP(NODE_OBJECT_PARENT) -// case CMD_INFO(NODE_ASM) { -// geo_writer->Write(NODE_ASM_OTR); -// auto param = cur_geo_cmd_s16(0x02); -// auto ptr = cur_geo_cmd_u32(0x04); -// -// geo_writer->Write(param); -// geo_writer->Write(SEGMENT_OFFSET(BSWAP32(ptr))); -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_BACKGROUND) { -// geo_writer->Write((uint8_t) NODE_BACKGROUND_OTR); -// auto bg = cur_geo_cmd_s16(0x02); -// geo_writer->Write(bg); -// -// auto ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x04))); -// geo_writer->Write(ptr); -// -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NOP) { -// geo_writer->Write((uint8_t) NOP); -// geo_writer->Write((uint32_t) 0); -// geo_writer->Write((uint32_t) 0); -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(COPY_VIEW) { -// geo_writer->Write((uint32_t) COPY_VIEW); -// auto idx = cur_geo_cmd_s16(0x02); -// geo_writer->Write(idx); -// break; -// } -// case CMD_INFO(NODE_HELD_OBJ) { -// geo_writer->Write((uint8_t) NODE_HELD_OBJ_OTR); -// -// auto idx = cur_geo_cmd_u8(0x01); -// geo_writer->Write(idx); -// -// Vec3s c_offset; -// read_vec3s(c_offset, (int16_t*) &cmd[0x02]); -// -// geo_writer->Write(c_offset[0]); -// geo_writer->Write(c_offset[1]); -// geo_writer->Write(c_offset[2]); -// -// auto ptr = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x08))); -// geo_writer->Write(ptr); -// -// cmd += 0x0C << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_SCALE) { -// geo_writer->Write(NODE_SCALE_OTR); -// auto params = cur_geo_cmd_u8(0x01); -// auto scale = cur_geo_cmd_u32(0x04); -// -// geo_writer->Write(params); -// geo_writer->Write(scale); -// -// if (params & 0x80) { -// auto dlist = SEGMENT_OFFSET(BSWAP32(cur_geo_cmd_u32(0x08))); -// auto decl = Companion::Instance->GetNodeByAddr(dlist); -// if(decl.has_value()){ -// uint64_t hash = CRC64(std::get<0>(decl.value()).c_str()); -// SPDLOG_INFO("Found display list: 0x{:X} Hash: 0x{:X} Path: {}", dlist, hash, std::get<0>(decl.value())); -// geo_writer->Write(hash); -// } else { -// SPDLOG_INFO("Warning: Could not find display list at 0x{:X}", dlist); -// geo_writer->Write((uint64_t) 0); -// } -// cmd += 4 << CMD_SIZE_SHIFT; -// } -// break; -// } -// case CMD_INFO(NOP2) { -// geo_writer->Write((uint8_t) NOP2); -// geo_writer->Write((uint32_t) 0); -// geo_writer->Write((uint32_t) 0); -// cmd += 0x08 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NOP3) { -// geo_writer->Write((uint8_t) NOP3); -// geo_writer->Write((uint32_t) 0); -// geo_writer->Write((uint32_t) 0); -// geo_writer->Write((uint32_t) 0); -// cmd += 0x10 << CMD_SIZE_SHIFT; -// break; -// } -// case CMD_INFO(NODE_CULLING_RADIUS) { -// geo_writer->Write((uint8_t) NODE_CULLING_RADIUS); -// auto radius = cur_geo_cmd_s16(0x02); -// geo_writer->Write(radius); -// break; -// } -// default: -// std::cout << "Unknown command: " << std::hex << (int) cmd[0x00] << std::endl; -// break; -// } -// } - - // auto size = geo_writer->GetLength(); - // auto data_ptr = geo_writer->ToVector();
\ No newline at end of file diff --git a/src/factories/sm64/TextFactory.cpp b/src/factories/sm64/TextFactory.cpp index e32d3ce..303cdac 100644 --- a/src/factories/sm64/TextFactory.cpp +++ b/src/factories/sm64/TextFactory.cpp @@ -1,5 +1,5 @@ #include "TextFactory.h" -#include "utils/MIODecoder.h" +#include "utils/Decompressor.h" void SM64::TextBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto writer = LUS::BinaryWriter(); @@ -11,16 +11,14 @@ void SM64::TextBinaryExporter::Export(std::ostream &write, std::shared_ptr<IPars writer.Finish(write); } -std::optional<std::shared_ptr<IParsedData>> SM64::TextFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& data) { - auto offset = data["offset"].as<size_t>(); - auto mio0 = data["mio0"].as<size_t>(); +std::optional<std::shared_ptr<IParsedData>> SM64::TextFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { std::vector<uint8_t> text; - auto decoded = MIO0Decoder::Decode(buffer, offset); - auto bytes = (uint8_t*) decoded.data(); + auto [_, segment] = Decompressor::AutoDecode(node, buffer); + size_t idx = 0; - while(bytes[mio0] != 0xFF){ - auto c = bytes[mio0++]; + while(segment.data[idx] != 0xFF){ + auto c = segment.data[idx++]; text.push_back(c); } text.push_back(0xFF); diff --git a/src/utils/Decompressor.cpp b/src/utils/Decompressor.cpp new file mode 100644 index 0000000..064adc6 --- /dev/null +++ b/src/utils/Decompressor.cpp @@ -0,0 +1,124 @@ +#include "Decompressor.h" + +#include <stdexcept> +#include "spdlog/spdlog.h" +#include <Companion.h> + +extern "C" { +#include <libmio0/mio0.h> +} + +std::unordered_map<uint32_t, DataChunk*> gCachedChunks; + +DataChunk* Decompressor::Decode(const std::vector<uint8_t>& buffer, const uint32_t offset, const CompressionType type) { + + if(gCachedChunks.contains(offset)){ + return gCachedChunks[offset]; + } + + const unsigned char* in_buf = buffer.data() + offset; + + switch (type) { + case CompressionType::MIO0: { + + mio0_header_t head; + if(!mio0_decode_header(in_buf, &head)){ + throw std::runtime_error("Failed to decode MIO0 header"); + } + + const auto decompressed = new uint8_t[head.dest_size]; + mio0_decode(in_buf, decompressed, nullptr); + gCachedChunks[offset] = new DataChunk{ decompressed, head.dest_size }; + return gCachedChunks[offset]; + } + default: + throw std::runtime_error("Unknown compression type"); + } +} + +DecompressedData Decompressor::AutoDecode(YAML::Node& node, std::vector<uint8_t>& buffer) { + if(!node["offset"]){ + throw std::runtime_error("Failed to find offset"); + } + + const auto offset = TranslateAddr(node["offset"].as<uint32_t>()); + + if(node["mio0"]){ + const auto mio0 = node["mio0"].as<uint32_t>(); + auto decoded = Decode(buffer, offset, CompressionType::MIO0); + auto size = node["size"] ? node["size"].as<size_t>() : decoded->size - mio0; + + return { + .root = decoded, + .segment = { decoded->data + mio0, size } + }; + } + + if(node["yay0"]){ + throw std::runtime_error("Yay0 not implemented"); + } + + if(node["yaz0"]){ + throw std::runtime_error("Yaz0 not implemented"); + } + + return { + .root = nullptr, + .segment = { buffer.data() + offset, buffer.size() - offset } + }; +} + +uint32_t Decompressor::TranslateAddr(uint32_t addr){ + if(IS_SEGMENTED(addr)){ + const auto segment = Companion::Instance->GetSegmentedAddr(SEGMENT_NUMBER(addr)); + + if(!segment.has_value()) { + SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(addr)); + return 0; + } + + return segment.value() + SEGMENT_OFFSET(addr); + } + + return addr; +} + +bool Decompressor::IsSegmented(uint32_t addr) { + if(IS_SEGMENTED(addr)){ + const auto segment = Companion::Instance->GetSegmentedAddr(SEGMENT_NUMBER(addr)); + + if(!segment.has_value()) { + SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(addr)); + return false; + } + + return true; + } + + return false; +} + +bool Decompressor::IsCompressed(YAML::Node& node) { + return node["mio0"] || node["yay0"] || node["yaz0"]; +} + +void Decompressor::CopyCompression(YAML::Node& from, YAML::Node& to){ + if(from["mio0"]){ + to["mio0"] = from["mio0"]; + } + + if(from["yay0"]){ + to["yay0"] = from["yay0"]; + } + + if(from["yaz0"]){ + to["yaz0"] = from["yaz0"]; + } +} + +void Decompressor::ClearCache() { + for(auto& [key, value] : gCachedChunks){ + delete value->data; + } + gCachedChunks.clear(); +} diff --git a/src/utils/Decompressor.h b/src/utils/Decompressor.h new file mode 100644 index 0000000..1bd5c05 --- /dev/null +++ b/src/utils/Decompressor.h @@ -0,0 +1,36 @@ +#pragma once + +#include <vector> +#include <cstdint> +#include <unordered_map> +#include <yaml-cpp/yaml.h> + +enum class CompressionType { + MIO0, + Yay0, + Yaz0, + None, +}; + + +struct DataChunk { + uint8_t* data; + size_t size; +}; + +struct DecompressedData { + DataChunk* root; + DataChunk segment; +}; + +class Decompressor { +public: + static DataChunk* Decode(const std::vector<uint8_t>& buffer, uint32_t offset, CompressionType type); + static DecompressedData AutoDecode(YAML::Node& node, std::vector<uint8_t>& buffer); + static uint32_t TranslateAddr(uint32_t addr); + static bool IsSegmented(uint32_t addr); + static bool IsCompressed(YAML::Node& node); + static void CopyCompression(YAML::Node& from, YAML::Node& to); + + static void ClearCache(); +};
\ No newline at end of file diff --git a/src/utils/MIODecoder.cpp b/src/utils/MIODecoder.cpp deleted file mode 100644 index 7574e55..0000000 --- a/src/utils/MIODecoder.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "MIODecoder.h" -#include <stdexcept> - -extern "C" { -#include <libmio0/mio0.h> -} - -std::unordered_map<uint32_t, std::vector<uint8_t>> MIO0Decoder::gCachedChunks; - -std::vector<uint8_t>& MIO0Decoder::Decode(std::vector<uint8_t>& buffer, uint32_t offset) { - const unsigned char* in_buf = buffer.data() + offset; - - mio0_header_t head; - if(!mio0_decode_header(in_buf, &head)){ - throw std::runtime_error("Failed to decode MIO0 header"); - } - - auto decompressed = new uint8_t[head.dest_size]; - mio0_decode(in_buf, decompressed, nullptr); - gCachedChunks[offset] = std::vector<uint8_t>(decompressed, decompressed + head.dest_size); - - delete[] decompressed; - return gCachedChunks[offset]; -} - -void MIO0Decoder::ClearCache() { - gCachedChunks.clear(); -} diff --git a/src/utils/MIODecoder.h b/src/utils/MIODecoder.h deleted file mode 100644 index ecf2ca4..0000000 --- a/src/utils/MIODecoder.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include <vector> -#include <unordered_map> -#include <cstdint> - -class MIO0Decoder { -public: - static std::unordered_map<uint32_t, std::vector<uint8_t>> gCachedChunks; - static std::vector<uint8_t>& Decode(std::vector<uint8_t>& buffer, uint32_t offset); - static void ClearCache(); -}; |
