diff --git a/src/keel/pack.cpp b/src/keel/pack.cpp index 252a0dad1..c35c44509 100644 --- a/src/keel/pack.cpp +++ b/src/keel/pack.cpp @@ -165,71 +165,6 @@ static ox::Error copyFS(ox::FileSystem *src, ox::FileSystem *dest) noexcept { return {}; } -// transformations need to be done after the copy to the new FS is complete -static ox::Error preloadObj( - ox::TypeStore *ts, ox::FileSystem *romFs, - GbaPreloader *pl, ox::CRStringView path) noexcept { - // load file - oxRequireM(buff, romFs->read(path)); - oxRequireM(obj, keel::readAsset(ts, buff)); - if (obj.type()->preloadable) { - oxOutf("preloading {}\n", path); - // preload - oxRequire(a, pl->startAlloc(ox::sizeOf(&obj))); - const auto err = ox::preload(pl, &obj); - oxReturnError(pl->endAlloc()); - oxReturnError(err); - const keel::PreloadPtr p{.preloadAddr = static_cast(a)}; - oxReturnError(ox::writeMC(&p).moveTo(&buff)); - } else { - // strip the Claw header (it is not needed after preloading) and write back out to dest fs - oxReturnError(ox::writeMC(&obj).moveTo(&buff)); - } - oxReturnError(romFs->write(path, buff.data(), buff.size())); - return {}; -} - -// claw file transformations are broken out because path to inode -// transformations need to be done after the copy to the new FS is complete -static ox::Error preloadDir(ox::TypeStore *ts, ox::FileSystem *romFs, GbaPreloader *pl, ox::CRStringView path) noexcept { - // copy - oxTracef("pack::preload", "path: {}", path); - oxRequire(fileList, romFs->ls(path)); - for (const auto &name : fileList) { - const auto filePath = ox::sfmt("{}{}", path, name); - oxRequire(stat, romFs->stat(filePath)); - if (stat.fileType == ox::FileType::Directory) { - const auto dir = ox::sfmt("{}{}/", path, name); - oxReturnError(preloadDir(ts, romFs, pl, dir)); - } else { - oxReturnError(preloadObj(ts, romFs, pl, filePath)); - } - } - return {}; -} - -static ox::Error padbin(ox::BufferWriter *w, unsigned factor) noexcept { - return w->write(nullptr, factor - w->buff().size() % factor); -} - -ox::Error appendBinary(ox::Buffer *binBuff, ox::Buffer *fsBuff, GbaPreloader *pl) noexcept { - constexpr ox::StringView mediaHdr = "KEEL_MEDIA_HEADER_______________"; - constexpr ox::StringView preloadHdr = "KEEL_PRELOAD_HEADER_____________"; - constexpr auto hdrSize = 32u; - static_assert(mediaHdr.bytes() == hdrSize); - static_assert(preloadHdr.bytes() == hdrSize); - ox::BufferWriter w(binBuff); - oxReturnError(padbin(&w, hdrSize)); - oxReturnError(w.write(mediaHdr.data(), mediaHdr.bytes())); - oxReturnError(w.write(fsBuff->data(), fsBuff->size())); - oxReturnError(padbin(&w, hdrSize)); - oxReturnError(w.write(preloadHdr.data(), preloadHdr.bytes())); - const auto &plBuff = pl->buff(); - oxReturnError(pl->offsetPtrs(binBuff->size())); - oxReturnError(w.write(plBuff.data(), plBuff.size())); - return {}; -} - ox::Error pack(keel::Context *ctx, ox::TypeStore *ts, ox::FileSystem *dest) noexcept { oxReturnError(copyFS(ctx->rom.get(), dest)); oxOut("Doing transforms\n"); @@ -237,11 +172,6 @@ ox::Error pack(keel::Context *ctx, ox::TypeStore *ts, ox::FileSystem *dest) noex return {}; } -ox::Error preload(ox::TypeStore *ts, ox::FileSystem *src, GbaPreloader *pl) noexcept { - oxOut("Preloading\n"); - return preloadDir(ts, src, pl, "/"); -} - } #endif diff --git a/src/keel/pack.hpp b/src/keel/pack.hpp index e3d21dc0f..5380dc354 100644 --- a/src/keel/pack.hpp +++ b/src/keel/pack.hpp @@ -7,6 +7,9 @@ #include #include +#include "asset.hpp" +#include "media.hpp" + namespace keel { class Context; @@ -76,10 +79,88 @@ struct GbaPlatSpec { using GbaPreloader = ox::Preloader; -ox::Error appendBinary(ox::Buffer *binBuff, ox::Buffer *fsBuff, GbaPreloader *pl) noexcept; +namespace detail { +// transformations need to be done after the copy to the new FS is complete +template +ox::Error preloadObj( + ox::TypeStore *ts, + ox::FileSystem *romFs, + ox::Preloader *pl, + ox::CRStringView path) noexcept { + // load file + oxRequireM(buff, romFs->read(path)); + oxRequireM(obj, keel::readAsset(ts, buff)); + if (obj.type()->preloadable) { + oxOutf("preloading {}\n", path); + // preload + oxRequire(a, pl->startAlloc(ox::sizeOf(&obj))); + const auto err = ox::preload(pl, &obj); + oxReturnError(pl->endAlloc()); + oxReturnError(err); + const keel::PreloadPtr p{.preloadAddr = static_cast(a)}; + oxReturnError(ox::writeMC(&p).moveTo(&buff)); + } else { + // strip the Claw header (it is not needed after preloading) and write back out to dest fs + oxReturnError(ox::writeMC(&obj).moveTo(&buff)); + } + oxReturnError(romFs->write(path, buff.data(), buff.size())); + return {}; +} + +// claw file transformations are broken out because path to inode +// transformations need to be done after the copy to the new FS is complete +template +ox::Error preloadDir( + ox::TypeStore *ts, + ox::FileSystem *romFs, + ox::Preloader *pl, + ox::CRStringView path) noexcept { + // copy + oxTracef("pack::preload", "path: {}", path); + oxRequire(fileList, romFs->ls(path)); + for (const auto &name : fileList) { + const auto filePath = ox::sfmt("{}{}", path, name); + oxRequire(stat, romFs->stat(filePath)); + if (stat.fileType == ox::FileType::Directory) { + const auto dir = ox::sfmt("{}{}/", path, name); + oxReturnError(preloadDir(ts, romFs, pl, dir)); + } else { + oxReturnError(preloadObj(ts, romFs, pl, filePath)); + } + } + return {}; +} + +} + +template +ox::Error appendBinary(ox::Buffer *binBuff, ox::Buffer *fsBuff, ox::Preloader *pl) noexcept { + constexpr auto padbin = [](ox::BufferWriter *w, unsigned factor) noexcept -> ox::Error { + return w->write(nullptr, factor - w->buff().size() % factor); + }; + constexpr ox::StringView mediaHdr = "KEEL_MEDIA_HEADER_______________"; + constexpr ox::StringView preloadHdr = "KEEL_PRELOAD_HEADER_____________"; + constexpr auto hdrSize = 32u; + static_assert(mediaHdr.bytes() == hdrSize); + static_assert(preloadHdr.bytes() == hdrSize); + ox::BufferWriter w(binBuff); + oxReturnError(padbin(&w, hdrSize)); + oxReturnError(w.write(mediaHdr.data(), mediaHdr.bytes())); + oxReturnError(w.write(fsBuff->data(), fsBuff->size())); + oxReturnError(padbin(&w, hdrSize)); + oxReturnError(w.write(preloadHdr.data(), preloadHdr.bytes())); + oxReturnError(pl->offsetPtrs(binBuff->size())); + const auto &plBuff = pl->buff(); + oxReturnError(w.write(plBuff.data(), plBuff.size())); + return {}; +} + +template +ox::Error preload(ox::TypeStore *ts, ox::FileSystem *src, ox::Preloader *pl) noexcept { + oxOut("Preloading\n"); + return detail::preloadDir(ts, src, pl, "/"); +} ox::Error pack(keel::Context *ctx, ox::TypeStore *ts, ox::FileSystem *dest) noexcept; -ox::Error preload(ox::TypeStore *ts, ox::FileSystem *src, GbaPreloader *pl) noexcept; - }