diff --git a/source/brres/Cargo.lock b/source/brres/Cargo.lock index 157d0ece3..ac6a62207 100644 --- a/source/brres/Cargo.lock +++ b/source/brres/Cargo.lock @@ -68,7 +68,7 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "brres" -version = "0.1.0" +version = "0.0.0" dependencies = [ "anyhow", "brres-sys", diff --git a/source/brres/Cargo.toml b/source/brres/Cargo.toml index 2b356ed7d..8365c2e32 100644 --- a/source/brres/Cargo.toml +++ b/source/brres/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "brres" license = "MIT" -version = "0.1.0" +version = "0.0.0" edition = "2021" description = "gctex is a Rust crate designed for encoding and decoding texture formats used in the Nintendo GameCube and Wii games. The library provides C bindings, making it useful in both Rust and C/C++ based projects." homepage = "https://github.com/riidefi/RiiStudio/tree/master/source/brres" diff --git a/source/brres/lib/brres-sys/src/bindings.cpp b/source/brres/lib/brres-sys/src/bindings.cpp index 327a8abe4..5d48b0d90 100644 --- a/source/brres/lib/brres-sys/src/bindings.cpp +++ b/source/brres/lib/brres-sys/src/bindings.cpp @@ -5,6 +5,10 @@ #include "./librii/g3d/data/Archive.hpp" +#include + +#include + bool gTestMode __attribute__((weak)) = false; namespace librii::g3d { @@ -55,19 +59,55 @@ static void SetCResult(CResult& result, DumpResult&& dumped) { }; } +struct Warning { + JS_OBJ(mclass, domain, body); + int mclass; + std::string domain; + std::string body; +}; + +struct ArchiveExtensions { + JS_OBJ(warnings); + std::vector warnings; +}; + extern "C" { WASM_EXPORT u32 imp_brres_read_from_bytes(CResult* result, const void* buf, u32 len) { std::span buf_span(reinterpret_cast(buf), reinterpret_cast(buf) + len); - auto arc = - librii::g3d::Archive::fromMemory(buf_span, "brres_read_from_bytes"); + + ArchiveExtensions ext; + + kpi::LightIOTransaction trans; + trans.callback = [&](kpi::IOMessageClass message_class, + const std::string_view domain, + const std::string_view message_body) { + ext.warnings.push_back(Warning{ + static_cast(message_class), + std::string(domain), + std::string(message_body), + }); + }; + auto arc = librii::g3d::Archive::fromMemory(buf_span, "brres_read_from_bytes", + trans); DumpResult dumped; bool ok = true; if (arc.has_value()) { dumped = librii::g3d::DumpJson(*arc); + + auto extJson = JS::serializeStruct(ext); + + // Assumes final character is a "}" + assert(dumped.jsonData.size() >= 1); + assert(dumped.jsonData[dumped.jsonData.size() - 1] == '}'); + dumped.jsonData.resize(dumped.jsonData.size() - 1); + // Assumes inital character is a "{" + assert(extJson.size() >= 1); + assert(extJson[0] == '{'); + dumped.jsonData = dumped.jsonData + "," + extJson.substr(1); } else { dumped.jsonData = arc.error(); ok = false; diff --git a/source/librii/g3d/io/ArchiveIO.cpp b/source/librii/g3d/io/ArchiveIO.cpp index ecae07f75..57d4df539 100644 --- a/source/librii/g3d/io/ArchiveIO.cpp +++ b/source/librii/g3d/io/ArchiveIO.cpp @@ -9,6 +9,8 @@ #include #include +#include + namespace librii::g3d { void TestJson(const librii::g3d::Archive& archive); @@ -50,7 +52,7 @@ Result> Archive::write() const { Result Archive::fromFile(std::string path, kpi::LightIOTransaction& transaction) { auto reader = TRY(oishii::BinaryReader::FromFilePath(path, std::endian::big)); - return fromMemory(reader.mBuf, path); + return fromMemory(reader.mBuf, path, transaction); } Result Archive::fromFile(std::string path) { kpi::LightIOTransaction trans; @@ -71,6 +73,24 @@ Result Archive::fromMemory(std::span buf, std::string path, kpi::LightIOTransaction& trans) { auto res = TRY(brres::read_from_bytes(buf)); auto arc = TRY(ReadJsonArc(res.jsonData, res.collatedBuffer)); + auto j = nlohmann::json::parse(res.jsonData); + if (j.contains("warnings") && j["warnings"].is_array()) { + for (auto& w : j["warnings"]) { + if (!j.contains("mclass") || !j["mclass"].is_number_unsigned()) { + continue; + } + if (!j.contains("domain") || !j["domain"].is_string()) { + continue; + } + if (!j.contains("body") || !j["body"].is_string()) { + continue; + } + int mclass = j["mclass"]; + std::string domain = j["domain"]; + std::string body = j["body"]; + trans.callback(static_cast(mclass), domain, body); + } + } return arc; } Result Archive::fromMemory(std::span buf, std::string path) { diff --git a/source/vendor/nlohmann/json.hpp b/source/vendor/nlohmann/json.hpp index a70aaf8cb..086896615 100644 --- a/source/vendor/nlohmann/json.hpp +++ b/source/vendor/nlohmann/json.hpp @@ -16454,7 +16454,7 @@ template , } } - throw std::out_of_range("key not found"); + JSON_THROW(std::out_of_range("key not found")); } const T& at(const Key& key) const @@ -16467,7 +16467,7 @@ template , } } - throw std::out_of_range("key not found"); + JSON_THROW(std::out_of_range("key not found")); } size_type erase(const Key& key)