#include "TitleDataFactory.h" #include "Companion.h" #include "utils/Decompressor.h" #include "spdlog/spdlog.h" // PM64 title data factory // Decompresses the Yay0-compressed "title_data" blob and extracts a sub-image // at the specified sub_offset with the specified size. // // Sub-images are byte-addressed (IA8 = 1 byte/pixel, RGBA32 = 4 bytes/pixel) // so no byte-swapping is needed. std::optional> PM64TitleDataFactory::parse(std::vector& buffer, YAML::Node& node) { auto offset = GetSafeNode(node, "offset"); auto subOffset = GetSafeNode(node, "sub_offset"); auto size = GetSafeNode(node, "size"); // Decompress Yay0 auto decoded = Decompressor::Decode(buffer, offset, CompressionType::YAY0); if (!decoded || decoded->size == 0) { SPDLOG_ERROR("PM64:TITLE_DATA: Failed to decompress YAY0 at offset 0x{:X}", offset); return std::nullopt; } if (subOffset + size > decoded->size) { SPDLOG_ERROR("PM64:TITLE_DATA: Sub-image at 0x{:X} + {} exceeds decompressed size {}", subOffset, size, decoded->size); return std::nullopt; } // Extract the sub-image (no byte-swap needed for IA8/RGBA32) std::vector result(size); std::memcpy(result.data(), decoded->data + subOffset, size); return std::make_shared(result); } ExportResult PM64TitleDataBinaryExporter::Export(std::ostream& write, std::shared_ptr raw, std::string& entryName, YAML::Node& node, std::string* replacement) { auto writer = LUS::BinaryWriter(); auto data = std::static_pointer_cast(raw)->mBuffer; WriteHeader(writer, Torch::ResourceType::Blob, 0); writer.Write(static_cast(data.size())); writer.Write(reinterpret_cast(data.data()), data.size()); writer.Finish(write); return std::nullopt; } ExportResult PM64TitleDataHeaderExporter::Export(std::ostream& write, std::shared_ptr raw, std::string& entryName, YAML::Node& node, std::string* replacement) { const auto symbol = GetSafeNode(node, "symbol", entryName); if (Companion::Instance->IsOTRMode()) { write << "static const ALIGN_ASSET(2) char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n"; return std::nullopt; } write << "extern u8 " << symbol << "[];\n"; return std::nullopt; }