Files
ox/src/nostalgia/tools/pack.cpp
T

95 lines
2.9 KiB
C++

/*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <fstream>
#include <ox/clargs/clargs.hpp>
#include <ox/fs/fs.hpp>
#include <ox/logconn/logconn.hpp>
#include <nostalgia/core/typestore.hpp>
#include "pack/pack.hpp"
using namespace nostalgia;
static ox::Error writeFileBuff(ox::CRStringView path, const ox::Buffer &buff) noexcept {
try {
std::ofstream f(std::string(toStdStringView(path)), std::ios::binary);
f.write(buff.data(), static_cast<intptr_t>(buff.size()));
} catch (const std::fstream::failure&) {
return OxError(2, "failed to write file");
}
return {};
}
static ox::Result<ox::Buffer> readFileBuff(ox::CRStringView path) noexcept {
std::ifstream file(std::string(toStdStringView(path)), std::ios::binary | std::ios::ate);
if (!file.good()) {
oxErrorf("Could not find OxFS file: {}", path);
return OxError(1, "Could not find OxFS file");
}
try {
const auto size = static_cast<std::size_t>(file.tellg());
ox::Buffer buff(size);
file.seekg(0, std::ios::beg);
file.read(buff.data(), static_cast<std::streamsize>(buff.size()));
return buff;
} catch (const std::ios_base::failure &e) {
oxErrorf("Could not read OxFS file: {}", e.what());
return OxError(2, "Could not read OxFS file");
}
}
static ox::Error run(const ox::ClArgs &args) noexcept {
const auto argSrc = args.getString("src", "");
const auto argRomBin = args.getString("rom-bin", "");
if (argSrc == "") {
oxErr("\033[31;1;1merror:\033[0m must specify a source directory\n");
return OxError(1, "must specify a source directory");
}
if (argRomBin == "") {
oxErr("\033[31;1;1merror:\033[0m must specify a path for ROM file\n");
return OxError(1, "must specify a path for preload file");
}
ox::Buffer dstBuff(32 * ox::units::MB);
oxReturnError(ox::FileSystem32::format(dstBuff.data(), dstBuff.size()));
ox::PassThroughFS src(argSrc);
ox::FileSystem32 dst(ox::FileStore32(dstBuff.data(), dstBuff.size()));
core::TypeStore ts(&src);
oxReturnError(pack(&ts, &src, &dst));
oxRequireM(pl, GbaPreloader::make());
oxReturnError(preload(&ts, &dst, pl.get()));
oxReturnError(dst.resize());
// resize buffer
oxRequire(dstSize, dst.size());
dstBuff.resize(dstSize);
oxRequireM(romBuff, readFileBuff(argRomBin));
oxReturnError(appendBinary(&romBuff, &dstBuff, pl.get()));
oxOutf("Dest FS size: {} bytes\n", dstSize);
oxOutf("Preload buff size: {} bytes\n", pl->buff().size());
oxOutf("ROM buff size: {} bytes\n", romBuff.size());
oxReturnError(writeFileBuff(argRomBin, romBuff));
return {};
}
int main(int argc, const char **args) {
ox::trace::init();
#ifdef DEBUG
ox::LoggerConn loggerConn;
const auto loggerErr = loggerConn.initConn("nost-pack");
if (loggerErr) {
oxErrf("Could not connect to logger: {} ({}:{})\n", toStr(loggerErr), loggerErr.file, loggerErr.line);
} else {
ox::trace::setLogger(&loggerConn);
}
#endif
const auto err = run(ox::ClArgs(argc, args));
oxAssert(err, "pack failed");
return static_cast<int>(err);
}