mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-08-12 20:22:37 -04:00
e1f372d6a5
soh-o2r-packer builds soh.o2r from soh/assets/custom, reproducing the ZAPD/OTRExporter archive exactly: 1,042 entries, 0 missing, 0 extra, 0 content mismatch, checked entry-wise because zip stores per-entry timestamps and whole-file hashes never match between runs. Most of it is torch's: Companion::Pack walks the directory, zips it and writes portVersion; BaseExporter::WriteHeader writes the resource header; TextureType and CalculateTextureSize come from TextureUtils. The packer stages the assets into the shape the archive should have and hands that over. Encoding a PNG into an N64 texture is the only piece nothing else provides -- torch decodes rom data that is already N64 format, never the reverse -- so PngTexture.cpp is the whole of what had to be written, and it follows ZAPD's quantisation rather than n64graphics', which scales where ZAPD shifts. GenerateSohOtr copies the libultraship shaders into assets/custom again before packing; assets/custom/shaders is gitignored and nothing else populates it, so a fresh clone would otherwise pack three files short. Removes prebuilt/ and its configure-time portVersion guard.
76 lines
2.5 KiB
C++
76 lines
2.5 KiB
C++
// Packs soh/assets/custom into soh.o2r -- the port's own assets, as opposed to anything
|
|
// extracted from a rom.
|
|
//
|
|
// usage: soh-o2r-packer <custom assets dir> <out.o2r> <M.m.p>
|
|
|
|
#include <algorithm>
|
|
#include <cstdio>
|
|
#include <filesystem>
|
|
#include <string>
|
|
|
|
#include "Companion.h"
|
|
#include "PngTexture.h"
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
int main(int argc, char** argv) {
|
|
if (argc != 4) {
|
|
fprintf(stderr, "usage: %s <custom assets dir> <out.o2r> <M.m.p>\n", argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
const fs::path assetsDir = argv[1];
|
|
const fs::path outPath = argv[2];
|
|
const std::string version = argv[3];
|
|
|
|
if (!fs::is_directory(assetsDir)) {
|
|
fprintf(stderr, "not a directory: %s\n", assetsDir.string().c_str());
|
|
return 1;
|
|
}
|
|
|
|
// Companion::Pack archives a directory as-is, so stage the assets in the shape the archive
|
|
// should have and let torch do the rest.
|
|
const fs::path stage = outPath.string() + ".stage";
|
|
std::error_code ec;
|
|
fs::remove_all(stage, ec);
|
|
fs::create_directories(stage);
|
|
|
|
for (const auto& entry : fs::recursive_directory_iterator(assetsDir)) {
|
|
if (!entry.is_regular_file()) {
|
|
continue;
|
|
}
|
|
|
|
const fs::path& path = entry.path();
|
|
const std::string rel = fs::relative(path, assetsDir).generic_string();
|
|
const std::string filename = path.filename().string();
|
|
|
|
// <name>.<format>.png becomes a texture resource archived as <name>
|
|
if (std::count(filename.begin(), filename.end(), '.') >= 2 && path.extension() == ".png") {
|
|
const std::string stem = path.stem().string();
|
|
const std::string format = stem.substr(stem.find_last_of('.') + 1);
|
|
|
|
if (PngTexture::IsFormat(format)) {
|
|
const std::string arc = rel.substr(0, rel.size() - (format.size() + 5));
|
|
if (!PngTexture::Convert(path, stage / arc, format)) {
|
|
return 1;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Only json is carried over from accessibility
|
|
if (rel.find("accessibility") != std::string::npos && path.extension() != ".json") {
|
|
continue;
|
|
}
|
|
|
|
fs::create_directories((stage / rel).parent_path());
|
|
fs::copy_file(path, stage / rel, fs::copy_options::overwrite_existing);
|
|
}
|
|
|
|
fs::remove(outPath, ec);
|
|
Companion::Pack(stage.string(), outPath.string(), ArchiveType::O2R, version);
|
|
fs::remove_all(stage, ec);
|
|
|
|
return 0;
|
|
}
|