[keel,nostalgia,studio] Make keel use references in place of a lot of pointers
This commit is contained in:
		@@ -12,7 +12,7 @@
 | 
			
		||||
namespace keel {
 | 
			
		||||
 | 
			
		||||
class Context;
 | 
			
		||||
using PackTransform = ox::Error(*)(Context*, ox::Buffer *clawData);
 | 
			
		||||
using PackTransform = ox::Error(*)(Context&, ox::Buffer &clawData);
 | 
			
		||||
 | 
			
		||||
class Context {
 | 
			
		||||
	public:
 | 
			
		||||
 
 | 
			
		||||
@@ -7,21 +7,21 @@
 | 
			
		||||
namespace keel {
 | 
			
		||||
 | 
			
		||||
ox::Error init(
 | 
			
		||||
		keel::Context *ctx,
 | 
			
		||||
		keel::Context &ctx,
 | 
			
		||||
		ox::UPtr<ox::FileSystem> &&fs,
 | 
			
		||||
		ox::CRStringView appName) noexcept {
 | 
			
		||||
	ctx->appName = appName;
 | 
			
		||||
	ctx.appName = appName;
 | 
			
		||||
	oxIgnoreError(setRomFs(ctx, std::move(fs)));
 | 
			
		||||
	#ifndef OX_BARE_METAL
 | 
			
		||||
	const auto &mods = modules();
 | 
			
		||||
	for (auto &mod : mods) {
 | 
			
		||||
		// register type converters
 | 
			
		||||
		for (auto c : mod->converters()) {
 | 
			
		||||
			ctx->converters.emplace_back(c);
 | 
			
		||||
			ctx.converters.emplace_back(c);
 | 
			
		||||
		}
 | 
			
		||||
		// register pack transforms
 | 
			
		||||
		for (auto c : mod->packTransforms()) {
 | 
			
		||||
			ctx->packTransforms.emplace_back(c);
 | 
			
		||||
			ctx.packTransforms.emplace_back(c);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	#endif
 | 
			
		||||
@@ -30,7 +30,7 @@ ox::Error init(
 | 
			
		||||
 | 
			
		||||
ox::Result<ox::UPtr<Context>> init(ox::UPtr<ox::FileSystem> &&fs, ox::CRStringView appName) noexcept {
 | 
			
		||||
	auto ctx = ox::make_unique<Context>();
 | 
			
		||||
	oxReturnError(keel::init(ctx.get(), std::move(fs), appName));
 | 
			
		||||
	oxReturnError(keel::init(*ctx, std::move(fs), appName));
 | 
			
		||||
	return ctx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
namespace keel {
 | 
			
		||||
 | 
			
		||||
ox::Error init(
 | 
			
		||||
		keel::Context *ctx,
 | 
			
		||||
		keel::Context &ctx,
 | 
			
		||||
		ox::UPtr<ox::FileSystem> &&fs,
 | 
			
		||||
		ox::CRStringView appName) noexcept;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,23 +41,23 @@ ox::Result<void*> findPreloadSection() noexcept {
 | 
			
		||||
	return OxError(1, "findPreloadSection is unsupported on this platform");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void clearUuidMap(Context *ctx) noexcept {
 | 
			
		||||
	ctx->uuidToPath.clear();
 | 
			
		||||
	ctx->pathToUuid.clear();
 | 
			
		||||
static void clearUuidMap(Context &ctx) noexcept {
 | 
			
		||||
	ctx.uuidToPath.clear();
 | 
			
		||||
	ctx.pathToUuid.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void createUuidMapping(Context *ctx, ox::String filePath, const ox::UUID &uuid) noexcept {
 | 
			
		||||
	ctx->pathToUuid[filePath] = uuid;
 | 
			
		||||
	ctx->uuidToPath[uuid.toString()] = std::move(filePath);
 | 
			
		||||
void createUuidMapping(Context &ctx, ox::String filePath, ox::UUID const&uuid) noexcept {
 | 
			
		||||
	ctx.pathToUuid[filePath] = uuid;
 | 
			
		||||
	ctx.uuidToPath[uuid.toString()] = std::move(filePath);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ox::Error buildUuidMap(Context *ctx, ox::CRStringView path) noexcept {
 | 
			
		||||
	oxRequire(files, ctx->rom->ls(path));
 | 
			
		||||
static ox::Error buildUuidMap(Context &ctx, ox::CRStringView path) noexcept {
 | 
			
		||||
	oxRequire(files, ctx.rom->ls(path));
 | 
			
		||||
	for (const auto &f : files) {
 | 
			
		||||
		oxRequire(filePath, ox::join("/", ox::Array<ox::StringView, 2>{path, f}));
 | 
			
		||||
		oxRequire(stat, ctx->rom->stat(filePath));
 | 
			
		||||
		oxRequire(stat, ctx.rom->stat(filePath));
 | 
			
		||||
		if (stat.fileType == ox::FileType::NormalFile) {
 | 
			
		||||
			oxRequire(data, ctx->rom->read(filePath));
 | 
			
		||||
			oxRequire(data, ctx.rom->read(filePath));
 | 
			
		||||
			const auto [hdr, err] = readAssetHeader(data);
 | 
			
		||||
			if (!err) {
 | 
			
		||||
				createUuidMapping(ctx, filePath, hdr.uuid);
 | 
			
		||||
@@ -71,8 +71,8 @@ static ox::Error buildUuidMap(Context *ctx, ox::CRStringView path) noexcept {
 | 
			
		||||
	return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ox::Error buildUuidMap(Context *ctx) noexcept {
 | 
			
		||||
	if (!ctx->rom) {
 | 
			
		||||
ox::Error buildUuidMap(Context &ctx) noexcept {
 | 
			
		||||
	if (!ctx.rom) {
 | 
			
		||||
		return OxError(1, "No ROM FS");
 | 
			
		||||
	}
 | 
			
		||||
	return buildUuidMap(ctx, "");
 | 
			
		||||
@@ -105,7 +105,7 @@ ox::Result<ox::String> uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept {
 | 
			
		||||
ox::Error performPackTransforms(Context &ctx, ox::Buffer &clawData) noexcept {
 | 
			
		||||
#ifndef OX_BARE_METAL
 | 
			
		||||
	for (auto tr : ctx.packTransforms) {
 | 
			
		||||
		oxReturnError(tr(&ctx, &clawData));
 | 
			
		||||
		oxReturnError(tr(ctx, clawData));
 | 
			
		||||
	}
 | 
			
		||||
	return {};
 | 
			
		||||
#else
 | 
			
		||||
@@ -123,10 +123,10 @@ ox::Error performPackTransforms(Context &ctx, ox::Buffer &clawData) noexcept {
 | 
			
		||||
 | 
			
		||||
namespace keel {
 | 
			
		||||
 | 
			
		||||
static void clearUuidMap(Context*) noexcept {
 | 
			
		||||
static void clearUuidMap(Context&) noexcept {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ox::Error buildUuidMap(Context*) noexcept {
 | 
			
		||||
ox::Error buildUuidMap(Context&) noexcept {
 | 
			
		||||
	return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -150,20 +150,20 @@ ox::Result<char*> loadRom(ox::CRStringView) noexcept {
 | 
			
		||||
void unloadRom(char*) noexcept {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ox::Result<std::size_t> getPreloadAddr(keel::Context *ctx, ox::CRStringView path) noexcept {
 | 
			
		||||
	oxRequire(stat, ctx->rom->stat(path));
 | 
			
		||||
	oxRequire(buff, static_cast<ox::MemFS*>(ctx->rom.get())->directAccess(path));
 | 
			
		||||
ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, ox::CRStringView path) noexcept {
 | 
			
		||||
	oxRequire(stat, ctx.rom->stat(path));
 | 
			
		||||
	oxRequire(buff, static_cast<ox::MemFS*>(ctx.rom.get())->directAccess(path));
 | 
			
		||||
	PreloadPtr p;
 | 
			
		||||
	oxReturnError(ox::readMC(buff, static_cast<std::size_t>(stat.size), &p));
 | 
			
		||||
	return static_cast<std::size_t>(p.preloadAddr) + ctx->preloadSectionOffset;
 | 
			
		||||
	return static_cast<std::size_t>(p.preloadAddr) + ctx.preloadSectionOffset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ox::Result<std::size_t> getPreloadAddr(keel::Context *ctx, const ox::FileAddress &file) noexcept {
 | 
			
		||||
	oxRequire(stat, ctx->rom->stat(file));
 | 
			
		||||
	oxRequire(buff, static_cast<ox::MemFS*>(ctx->rom.get())->directAccess(file));
 | 
			
		||||
ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, const ox::FileAddress &file) noexcept {
 | 
			
		||||
	oxRequire(stat, ctx.rom->stat(file));
 | 
			
		||||
	oxRequire(buff, static_cast<ox::MemFS*>(ctx.rom.get())->directAccess(file));
 | 
			
		||||
	PreloadPtr p;
 | 
			
		||||
	oxReturnError(ox::readMC(buff, static_cast<std::size_t>(stat.size), &p));
 | 
			
		||||
	return static_cast<std::size_t>(p.preloadAddr) + ctx->preloadSectionOffset;
 | 
			
		||||
	return static_cast<std::size_t>(p.preloadAddr) + ctx.preloadSectionOffset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -172,8 +172,8 @@ ox::Result<std::size_t> getPreloadAddr(keel::Context *ctx, const ox::FileAddress
 | 
			
		||||
 | 
			
		||||
namespace keel {
 | 
			
		||||
 | 
			
		||||
ox::Error setRomFs(Context *ctx, ox::UPtr<ox::FileSystem> fs) noexcept {
 | 
			
		||||
	ctx->rom = std::move(fs);
 | 
			
		||||
ox::Error setRomFs(Context &ctx, ox::UPtr<ox::FileSystem> fs) noexcept {
 | 
			
		||||
	ctx.rom = std::move(fs);
 | 
			
		||||
	clearUuidMap(ctx);
 | 
			
		||||
	return buildUuidMap(ctx);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,17 +29,17 @@ oxModelBegin(PreloadPtr)
 | 
			
		||||
	oxModelField(preloadAddr)
 | 
			
		||||
oxModelEnd()
 | 
			
		||||
 | 
			
		||||
ox::Result<std::size_t> getPreloadAddr(keel::Context *ctx, const ox::FileAddress &file) noexcept;
 | 
			
		||||
ox::Result<std::size_t> getPreloadAddr(keel::Context *ctx, ox::CRStringView file) noexcept;
 | 
			
		||||
ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, const ox::FileAddress &file) noexcept;
 | 
			
		||||
ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, ox::CRStringView file) noexcept;
 | 
			
		||||
 | 
			
		||||
#ifndef OX_BARE_METAL
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
ox::Result<keel::AssetRef<T>> readObjFile(
 | 
			
		||||
		keel::Context *ctx,
 | 
			
		||||
		keel::Context &ctx,
 | 
			
		||||
		ox::StringView assetId,
 | 
			
		||||
		bool forceLoad) noexcept {
 | 
			
		||||
	constexpr auto readConvert = [](Context *ctx, const ox::Buffer &buff) -> ox::Result<T> {
 | 
			
		||||
	constexpr auto readConvert = [](Context &ctx, const ox::Buffer &buff) -> ox::Result<T> {
 | 
			
		||||
		auto [obj, err] = readAsset<T>(buff);
 | 
			
		||||
		if (err) {
 | 
			
		||||
			if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) {
 | 
			
		||||
@@ -53,23 +53,23 @@ ox::Result<keel::AssetRef<T>> readObjFile(
 | 
			
		||||
	ox::UUIDStr uuidStr;
 | 
			
		||||
	if (beginsWith(assetId, "uuid://")) {
 | 
			
		||||
		assetId = substr(assetId, 7);
 | 
			
		||||
		path = ctx->uuidToPath[assetId];
 | 
			
		||||
		path = ctx.uuidToPath[assetId];
 | 
			
		||||
	} else {
 | 
			
		||||
		path = assetId;
 | 
			
		||||
		uuidStr = ctx->pathToUuid[path].toString();
 | 
			
		||||
		uuidStr = ctx.pathToUuid[path].toString();
 | 
			
		||||
		assetId = uuidStr;
 | 
			
		||||
	}
 | 
			
		||||
	if (forceLoad) {
 | 
			
		||||
		oxRequire(buff, ctx->rom->read(path));
 | 
			
		||||
		oxRequire(buff, ctx.rom->read(path));
 | 
			
		||||
		oxRequire(obj, readConvert(ctx, buff));
 | 
			
		||||
		oxRequire(cached, ctx->assetManager.setAsset(assetId, obj));
 | 
			
		||||
		oxRequire(cached, ctx.assetManager.setAsset(assetId, obj));
 | 
			
		||||
		return cached;
 | 
			
		||||
	} else {
 | 
			
		||||
		auto [cached, err] = ctx->assetManager.getAsset<T>(assetId);
 | 
			
		||||
		auto [cached, err] = ctx.assetManager.getAsset<T>(assetId);
 | 
			
		||||
		if (err) {
 | 
			
		||||
			oxRequire(buff, ctx->rom->read(path));
 | 
			
		||||
			oxRequire(buff, ctx.rom->read(path));
 | 
			
		||||
			oxRequire(obj, readConvert(ctx, buff));
 | 
			
		||||
			oxReturnError(ctx->assetManager.setAsset(assetId, obj).moveTo(&cached));
 | 
			
		||||
			oxReturnError(ctx.assetManager.setAsset(assetId, obj).moveTo(&cached));
 | 
			
		||||
		}
 | 
			
		||||
		return cached;
 | 
			
		||||
	}
 | 
			
		||||
@@ -79,7 +79,7 @@ ox::Result<keel::AssetRef<T>> readObjFile(
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
ox::Result<keel::AssetRef<T>> readObjNoCache(
 | 
			
		||||
		keel::Context *ctx,
 | 
			
		||||
		keel::Context &ctx,
 | 
			
		||||
		ox::CRStringView assetId) noexcept {
 | 
			
		||||
	if constexpr(ox::preloadable<T>::value) {
 | 
			
		||||
		oxRequire(addr, getPreloadAddr(ctx, assetId));
 | 
			
		||||
@@ -91,9 +91,9 @@ ox::Result<keel::AssetRef<T>> readObjNoCache(
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void createUuidMapping(Context *ctx, ox::String filePath, const ox::UUID &uuid) noexcept;
 | 
			
		||||
void createUuidMapping(Context &ctx, ox::String filePath, ox::UUID const&uuid) noexcept;
 | 
			
		||||
 | 
			
		||||
ox::Error buildUuidMap(Context *ctx) noexcept;
 | 
			
		||||
ox::Error buildUuidMap(Context &ctx) noexcept;
 | 
			
		||||
 | 
			
		||||
ox::Result<ox::String> uuidToPath(Context &ctx, ox::CRStringView uuid) noexcept;
 | 
			
		||||
 | 
			
		||||
@@ -102,19 +102,19 @@ ox::Result<ox::String> uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept;
 | 
			
		||||
ox::Error performPackTransforms(Context &ctx, ox::Buffer &clawData) noexcept;
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
ox::Result<AssetRef<T>> setAsset(keel::Context *ctx, ox::StringView assetId, T const&asset) noexcept {
 | 
			
		||||
ox::Result<AssetRef<T>> setAsset(keel::Context &ctx, ox::StringView assetId, T const&asset) noexcept {
 | 
			
		||||
#ifndef OX_BARE_METAL
 | 
			
		||||
	if (assetId.len() == 0) {
 | 
			
		||||
		return OxError(1, "Invalid asset ID");
 | 
			
		||||
	}
 | 
			
		||||
	ox::UUIDStr idStr;
 | 
			
		||||
	if (assetId[0] == '/') {
 | 
			
		||||
		const auto [id, err] = ctx->pathToUuid.at(assetId);
 | 
			
		||||
		const auto [id, err] = ctx.pathToUuid.at(assetId);
 | 
			
		||||
		oxReturnError(err);
 | 
			
		||||
		idStr = id->toString();
 | 
			
		||||
		assetId = idStr;
 | 
			
		||||
	}
 | 
			
		||||
	return ctx->assetManager.setAsset(assetId, asset);
 | 
			
		||||
	return ctx.assetManager.setAsset(assetId, asset);
 | 
			
		||||
#else
 | 
			
		||||
	return OxError(1, "Not supported on this platform");
 | 
			
		||||
#endif
 | 
			
		||||
@@ -122,7 +122,7 @@ ox::Result<AssetRef<T>> setAsset(keel::Context *ctx, ox::StringView assetId, T c
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
ox::Result<keel::AssetRef<T>> readObj(
 | 
			
		||||
		keel::Context *ctx,
 | 
			
		||||
		keel::Context &ctx,
 | 
			
		||||
		ox::CRStringView assetId,
 | 
			
		||||
		[[maybe_unused]] bool forceLoad = false) noexcept {
 | 
			
		||||
#ifndef OX_BARE_METAL
 | 
			
		||||
@@ -134,8 +134,8 @@ ox::Result<keel::AssetRef<T>> readObj(
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
ox::Result<keel::AssetRef<T>> readObj(
 | 
			
		||||
		keel::Context *ctx,
 | 
			
		||||
		const ox::FileAddress &file,
 | 
			
		||||
		keel::Context &ctx,
 | 
			
		||||
		ox::FileAddress const&file,
 | 
			
		||||
		[[maybe_unused]] bool forceLoad = false) noexcept {
 | 
			
		||||
#ifndef OX_BARE_METAL
 | 
			
		||||
	oxRequire(assetId, file.getPath());
 | 
			
		||||
@@ -152,15 +152,15 @@ ox::Result<keel::AssetRef<T>> readObj(
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
ox::Error writeObj(
 | 
			
		||||
		keel::Context *ctx,
 | 
			
		||||
		const ox::FileAddress &file,
 | 
			
		||||
		const T &obj,
 | 
			
		||||
		keel::Context &ctx,
 | 
			
		||||
		ox::FileAddress const&file,
 | 
			
		||||
		T const&obj,
 | 
			
		||||
		ox::ClawFormat fmt = ox::ClawFormat::Metal) noexcept {
 | 
			
		||||
	oxRequire(objBuff, ox::writeClaw(obj, fmt));
 | 
			
		||||
	return ctx->rom->write(file, objBuff.data(), objBuff.size());
 | 
			
		||||
	return ctx.rom->write(file, objBuff.data(), objBuff.size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ox::Error setRomFs(Context *ctx, ox::UPtr<ox::FileSystem> fs) noexcept;
 | 
			
		||||
ox::Error setRomFs(Context &ctx, ox::UPtr<ox::FileSystem> fs) noexcept;
 | 
			
		||||
 | 
			
		||||
ox::Result<ox::UniquePtr<ox::FileSystem>> loadRomFs(ox::CRStringView path) noexcept;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,12 +12,12 @@ namespace keel {
 | 
			
		||||
#ifndef OX_BARE_METAL
 | 
			
		||||
[[nodiscard]]
 | 
			
		||||
static ox::Result<const BaseConverter*> findConverter(
 | 
			
		||||
		keel::Context *ctx,
 | 
			
		||||
		keel::Context &ctx,
 | 
			
		||||
		ox::CRStringView srcTypeName,
 | 
			
		||||
		int srcTypeVersion,
 | 
			
		||||
		ox::CRStringView dstTypeName,
 | 
			
		||||
		int dstTypeVersion) noexcept {
 | 
			
		||||
	for (auto &c : ctx->converters) {
 | 
			
		||||
	for (auto &c : ctx.converters) {
 | 
			
		||||
		if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) {
 | 
			
		||||
			return c;
 | 
			
		||||
		}
 | 
			
		||||
@@ -26,7 +26,7 @@ static ox::Result<const BaseConverter*> findConverter(
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static ox::Result<ox::UniquePtr<Wrap>> convert(
 | 
			
		||||
		[[maybe_unused]] keel::Context *ctx,
 | 
			
		||||
		[[maybe_unused]] keel::Context &ctx,
 | 
			
		||||
		[[maybe_unused]] const ox::Buffer &srcBuffer,
 | 
			
		||||
		[[maybe_unused]] ox::CRStringView srcTypeName,
 | 
			
		||||
		[[maybe_unused]] int srcTypeVersion,
 | 
			
		||||
@@ -38,7 +38,7 @@ static ox::Result<ox::UniquePtr<Wrap>> convert(
 | 
			
		||||
		return c->convertBuffToPtr(ctx, srcBuffer);
 | 
			
		||||
	}
 | 
			
		||||
	// try to chain multiple converters
 | 
			
		||||
	for (const auto &subConverter : ctx->converters) {
 | 
			
		||||
	for (const auto &subConverter : ctx.converters) {
 | 
			
		||||
		if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
@@ -46,7 +46,7 @@ static ox::Result<ox::UniquePtr<Wrap>> convert(
 | 
			
		||||
			convert(ctx, srcBuffer, srcTypeName, srcTypeVersion,
 | 
			
		||||
			        subConverter->srcTypeName(), subConverter->srcTypeVersion());
 | 
			
		||||
		if (!chainErr) {
 | 
			
		||||
			return subConverter->convertPtrToPtr(ctx, intermediate.get());
 | 
			
		||||
			return subConverter->convertPtrToPtr(ctx, *intermediate);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return OxError(1, "Could not convert between types");
 | 
			
		||||
@@ -54,7 +54,7 @@ static ox::Result<ox::UniquePtr<Wrap>> convert(
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
ox::Result<ox::UniquePtr<Wrap>> convert(
 | 
			
		||||
		[[maybe_unused]] keel::Context *ctx,
 | 
			
		||||
		[[maybe_unused]] keel::Context &ctx,
 | 
			
		||||
		[[maybe_unused]] const ox::Buffer &srcBuffer,
 | 
			
		||||
		[[maybe_unused]] ox::CRStringView dstTypeName,
 | 
			
		||||
		[[maybe_unused]] int dstTypeVersion) noexcept {
 | 
			
		||||
 
 | 
			
		||||
@@ -67,8 +67,8 @@ constexpr auto makeWrap(Args &&...args) noexcept {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
constexpr auto wrapCast(auto ptr) noexcept {
 | 
			
		||||
	return static_cast<WrapInline<T>*>(ptr)->obj();
 | 
			
		||||
constexpr T *wrapCast(Wrap &ptr) noexcept {
 | 
			
		||||
	return static_cast<WrapInline<T>&>(ptr).obj();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BaseConverter {
 | 
			
		||||
@@ -87,13 +87,14 @@ class BaseConverter {
 | 
			
		||||
		[[nodiscard]]
 | 
			
		||||
		virtual bool dstMatches(ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept = 0;
 | 
			
		||||
 | 
			
		||||
		virtual ox::Result<ox::UniquePtr<Wrap>> convertPtrToPtr(keel::Context *ctx, Wrap *src) const noexcept = 0;
 | 
			
		||||
		virtual ox::Result<ox::UniquePtr<Wrap>> convertPtrToPtr(keel::Context &ctx, Wrap &src) const noexcept = 0;
 | 
			
		||||
 | 
			
		||||
		virtual ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(keel::Context *ctx, const ox::Buffer &srcBuff) const noexcept = 0;
 | 
			
		||||
		virtual ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(keel::Context &ctx, const ox::Buffer &srcBuff) const noexcept = 0;
 | 
			
		||||
 | 
			
		||||
		[[nodiscard]]
 | 
			
		||||
		inline bool matches(ox::CRStringView srcTypeName, int srcTypeVersion,
 | 
			
		||||
								  ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept {
 | 
			
		||||
		inline bool matches(
 | 
			
		||||
				ox::CRStringView srcTypeName, int srcTypeVersion,
 | 
			
		||||
				ox::CRStringView dstTypeName, int dstTypeVersion) const noexcept {
 | 
			
		||||
			return srcMatches(srcTypeName, srcTypeVersion)
 | 
			
		||||
				 && dstMatches(dstTypeName, dstTypeVersion);
 | 
			
		||||
		}
 | 
			
		||||
@@ -129,29 +130,30 @@ class Converter: public BaseConverter {
 | 
			
		||||
				 && dstTypeVersion == DstTypeVersion;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ox::Result<ox::UniquePtr<Wrap>> convertPtrToPtr(keel::Context *ctx, Wrap *src) const noexcept final {
 | 
			
		||||
		ox::Result<ox::UniquePtr<Wrap>> convertPtrToPtr(keel::Context &ctx, Wrap &src) const noexcept final {
 | 
			
		||||
			auto dst = makeWrap<DstType>();
 | 
			
		||||
			oxReturnError(convert(ctx, wrapCast<SrcType>(src), wrapCast<DstType>(dst.get())));
 | 
			
		||||
			oxReturnError(convert(ctx, *wrapCast<SrcType>(src), *wrapCast<DstType>(*dst)));
 | 
			
		||||
			return ox::Result<ox::UniquePtr<Wrap>>(std::move(dst));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(keel::Context *ctx, const ox::Buffer &srcBuff) const noexcept final {
 | 
			
		||||
		ox::Result<ox::UniquePtr<Wrap>> convertBuffToPtr(keel::Context &ctx, ox::Buffer const&srcBuff) const noexcept final {
 | 
			
		||||
			oxRequireM(src, readAsset<SrcType>(srcBuff));
 | 
			
		||||
			auto dst = makeWrap<DstType>();
 | 
			
		||||
			oxReturnError(convert(ctx, &src, wrapCast<DstType>(dst.get())));
 | 
			
		||||
			oxReturnError(convert(ctx, src, *wrapCast<DstType>(*dst)));
 | 
			
		||||
			return ox::Result<ox::UniquePtr<Wrap>>(std::move(dst));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		virtual ox::Error convert(keel::Context *ctx, SrcType*, DstType*) const noexcept = 0;
 | 
			
		||||
		virtual ox::Error convert(keel::Context &ctx, SrcType&, DstType&) const noexcept = 0;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ox::Result<ox::UniquePtr<Wrap>> convert(keel::Context *ctx, const ox::Buffer &srcBuffer,
 | 
			
		||||
                                        ox::CRStringView dstTypeName, int dstTypeVersion) noexcept;
 | 
			
		||||
ox::Result<ox::UniquePtr<Wrap>> convert(
 | 
			
		||||
		keel::Context &ctx, const ox::Buffer &srcBuffer,
 | 
			
		||||
		ox::CRStringView dstTypeName, int dstTypeVersion) noexcept;
 | 
			
		||||
 | 
			
		||||
template<typename DstType>
 | 
			
		||||
ox::Result<DstType> convert(keel::Context *ctx, const ox::Buffer &srcBuffer) noexcept {
 | 
			
		||||
ox::Result<DstType> convert(keel::Context &ctx, const ox::Buffer &srcBuffer) noexcept {
 | 
			
		||||
	static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
 | 
			
		||||
	static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
 | 
			
		||||
	oxRequire(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion));
 | 
			
		||||
@@ -159,29 +161,29 @@ ox::Result<DstType> convert(keel::Context *ctx, const ox::Buffer &srcBuffer) noe
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename DstType>
 | 
			
		||||
ox::Error convert(keel::Context *ctx, const ox::Buffer &buff, DstType *outObj) noexcept {
 | 
			
		||||
ox::Error convert(keel::Context &ctx, const ox::Buffer &buff, DstType *outObj) noexcept {
 | 
			
		||||
	static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
 | 
			
		||||
	static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
 | 
			
		||||
	oxRequire(outPtr, convert(ctx, buff, DstTypeName, DstTypeVersion));
 | 
			
		||||
	*outObj = std::move(*wrapCast<DstType>(outPtr.get()));
 | 
			
		||||
	*outObj = std::move(*wrapCast<DstType>(*outPtr));
 | 
			
		||||
	return OxError(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename DstType>
 | 
			
		||||
ox::Result<ox::Buffer> convertBuffToBuff(keel::Context *ctx, const ox::Buffer &srcBuffer, ox::ClawFormat fmt) noexcept {
 | 
			
		||||
ox::Result<ox::Buffer> convertBuffToBuff(keel::Context &ctx, const ox::Buffer &srcBuffer, ox::ClawFormat fmt) noexcept {
 | 
			
		||||
	static constexpr auto DstTypeName = ox::requireModelTypeName<DstType>();
 | 
			
		||||
	static constexpr auto DstTypeVersion = ox::requireModelTypeVersion<DstType>();
 | 
			
		||||
	oxRequire(out, convert(ctx, srcBuffer, DstTypeName, DstTypeVersion));
 | 
			
		||||
	return ox::writeClaw<DstType>(*wrapCast<DstType>(out.get()), fmt);
 | 
			
		||||
	return ox::writeClaw<DstType>(*wrapCast<DstType>(*out), fmt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename From, typename To, ox::ClawFormat fmt = ox::ClawFormat::Metal>
 | 
			
		||||
auto transformRule(keel::Context *ctx, ox::Buffer *buff) noexcept -> ox::Error {
 | 
			
		||||
	oxRequire(hdr, readAssetHeader(*buff));
 | 
			
		||||
auto transformRule(keel::Context &ctx, ox::Buffer &buff) noexcept -> ox::Error {
 | 
			
		||||
	oxRequire(hdr, readAssetHeader(buff));
 | 
			
		||||
	const auto typeId = ox::buildTypeId(
 | 
			
		||||
			hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams);
 | 
			
		||||
	if (typeId == ox::buildTypeId<From>()) {
 | 
			
		||||
		oxReturnError(keel::convertBuffToBuff<To>(ctx, *buff, fmt).moveTo(buff));
 | 
			
		||||
		oxReturnError(keel::convertBuffToBuff<To>(ctx, buff, fmt).moveTo(&buff));
 | 
			
		||||
	}
 | 
			
		||||
	return {};
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -52,15 +52,15 @@ class KeelModule: public keel::Module {
 | 
			
		||||
		ox::Vector<keel::PackTransform> packTransforms() const noexcept final {
 | 
			
		||||
			return {
 | 
			
		||||
				// convert tilesheets to CompactTileSheets
 | 
			
		||||
				[](keel::Context *ctx, ox::Buffer *buff) -> ox::Error {
 | 
			
		||||
					oxRequire(hdr, keel::readAssetHeader(*buff));
 | 
			
		||||
				[](keel::Context &ctx, ox::Buffer &buff) -> ox::Error {
 | 
			
		||||
					oxRequire(hdr, keel::readAssetHeader(buff));
 | 
			
		||||
					const auto typeId = ox::buildTypeId(
 | 
			
		||||
							hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, hdr.clawHdr.typeParams);
 | 
			
		||||
					if (typeId == ox::buildTypeId<TileSheetV1>() ||
 | 
			
		||||
						 typeId == ox::buildTypeId<TileSheetV2>() ||
 | 
			
		||||
						 typeId == ox::buildTypeId<TileSheet>()) {
 | 
			
		||||
						oxReturnError(keel::convertBuffToBuff<core::CompactTileSheet>(
 | 
			
		||||
									ctx, *buff, ox::ClawFormat::Metal).moveTo(buff));
 | 
			
		||||
								ctx, buff, ox::ClawFormat::Metal).moveTo(&buff));
 | 
			
		||||
					}
 | 
			
		||||
					return {};
 | 
			
		||||
				},
 | 
			
		||||
 
 | 
			
		||||
@@ -7,60 +7,60 @@
 | 
			
		||||
namespace nostalgia::core {
 | 
			
		||||
 | 
			
		||||
ox::Error NostalgiaPaletteToPaletteConverter::convert(
 | 
			
		||||
		keel::Context*,
 | 
			
		||||
		NostalgiaPalette *src,
 | 
			
		||||
		Palette *dst) const noexcept {
 | 
			
		||||
	dst->colors = std::move(src->colors);
 | 
			
		||||
		keel::Context&,
 | 
			
		||||
		NostalgiaPalette &src,
 | 
			
		||||
		Palette &dst) const noexcept {
 | 
			
		||||
	dst.colors = std::move(src.colors);
 | 
			
		||||
	return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ox::Error TileSheetV1ToTileSheetConverter::convert(
 | 
			
		||||
		keel::Context*,
 | 
			
		||||
		TileSheetV1 *src,
 | 
			
		||||
		TileSheet *dst) const noexcept {
 | 
			
		||||
	dst->bpp              = src->bpp;
 | 
			
		||||
	dst->defaultPalette   = std::move(src->defaultPalette);
 | 
			
		||||
	dst->subsheet.name    = "Root";
 | 
			
		||||
	dst->subsheet.rows    = src->rows;
 | 
			
		||||
	dst->subsheet.columns = src->columns;
 | 
			
		||||
	dst->subsheet.pixels  = std::move(src->pixels);
 | 
			
		||||
		keel::Context&,
 | 
			
		||||
		TileSheetV1 &src,
 | 
			
		||||
		TileSheet &dst) const noexcept {
 | 
			
		||||
	dst.bpp              = src.bpp;
 | 
			
		||||
	dst.defaultPalette   = std::move(src.defaultPalette);
 | 
			
		||||
	dst.subsheet.name    = "Root";
 | 
			
		||||
	dst.subsheet.rows    = src.rows;
 | 
			
		||||
	dst.subsheet.columns = src.columns;
 | 
			
		||||
	dst.subsheet.pixels  = std::move(src.pixels);
 | 
			
		||||
	return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ox::Error TileSheetToCompactTileSheetConverter::convert(
 | 
			
		||||
		keel::Context*,
 | 
			
		||||
		TileSheet *src,
 | 
			
		||||
		CompactTileSheet *dst) const noexcept {
 | 
			
		||||
	dst->bpp            = src->bpp;
 | 
			
		||||
	dst->defaultPalette = std::move(src->defaultPalette);
 | 
			
		||||
	dst->pixels         = src->pixels();
 | 
			
		||||
		keel::Context&,
 | 
			
		||||
		TileSheet &src,
 | 
			
		||||
		CompactTileSheet &dst) const noexcept {
 | 
			
		||||
	dst.bpp            = src.bpp;
 | 
			
		||||
	dst.defaultPalette = std::move(src.defaultPalette);
 | 
			
		||||
	dst.pixels         = src.pixels();
 | 
			
		||||
	return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void TileSheetV2ToTileSheetConverter::convertSubsheet(
 | 
			
		||||
		TileSheetV2::SubSheet *src,
 | 
			
		||||
		TileSheet::SubSheet *dst,
 | 
			
		||||
		SubSheetId *idIt) noexcept {
 | 
			
		||||
	dst->id      = *idIt;
 | 
			
		||||
	dst->name    = std::move(src->name);
 | 
			
		||||
	dst->columns = src->columns;
 | 
			
		||||
	dst->rows    = src->rows;
 | 
			
		||||
	dst->pixels  = std::move(src->pixels);
 | 
			
		||||
	++*idIt;
 | 
			
		||||
	dst->subsheets.resize(src->subsheets.size());
 | 
			
		||||
	for (auto i = 0u; i < src->subsheets.size(); ++i) {
 | 
			
		||||
		convertSubsheet(&src->subsheets[i], &dst->subsheets[i], idIt);
 | 
			
		||||
		TileSheetV2::SubSheet &src,
 | 
			
		||||
		TileSheet::SubSheet &dst,
 | 
			
		||||
		SubSheetId &idIt) noexcept {
 | 
			
		||||
	dst.id      = idIt;
 | 
			
		||||
	dst.name    = std::move(src.name);
 | 
			
		||||
	dst.columns = src.columns;
 | 
			
		||||
	dst.rows    = src.rows;
 | 
			
		||||
	dst.pixels  = std::move(src.pixels);
 | 
			
		||||
	++idIt;
 | 
			
		||||
	dst.subsheets.resize(src.subsheets.size());
 | 
			
		||||
	for (auto i = 0u; i < src.subsheets.size(); ++i) {
 | 
			
		||||
		convertSubsheet(src.subsheets[i], dst.subsheets[i], idIt);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ox::Error TileSheetV2ToTileSheetConverter::convert(
 | 
			
		||||
		keel::Context*,
 | 
			
		||||
		TileSheetV2 *src,
 | 
			
		||||
		TileSheet *dst) const noexcept {
 | 
			
		||||
	dst->bpp            = src->bpp;
 | 
			
		||||
	dst->defaultPalette = std::move(src->defaultPalette);
 | 
			
		||||
	convertSubsheet(&src->subsheet, &dst->subsheet, &dst->idIt);
 | 
			
		||||
		keel::Context&,
 | 
			
		||||
		TileSheetV2 &src,
 | 
			
		||||
		TileSheet &dst) const noexcept {
 | 
			
		||||
	dst.bpp            = src.bpp;
 | 
			
		||||
	dst.defaultPalette = std::move(src.defaultPalette);
 | 
			
		||||
	convertSubsheet(src.subsheet, dst.subsheet, dst.idIt);
 | 
			
		||||
	return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,24 +17,24 @@ namespace nostalgia::core {
 | 
			
		||||
// Type converters
 | 
			
		||||
 | 
			
		||||
class NostalgiaPaletteToPaletteConverter: public keel::Converter<NostalgiaPalette, Palette> {
 | 
			
		||||
	ox::Error convert(keel::Context*, NostalgiaPalette *src, Palette *dst) const noexcept final;
 | 
			
		||||
	ox::Error convert(keel::Context&, NostalgiaPalette &src, Palette &dst) const noexcept final;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class TileSheetV1ToTileSheetConverter: public keel::Converter<TileSheetV1, TileSheet> {
 | 
			
		||||
	ox::Error convert(keel::Context*, TileSheetV1 *src, TileSheet *dst) const noexcept final;
 | 
			
		||||
	ox::Error convert(keel::Context&, TileSheetV1 &src, TileSheet &dst) const noexcept final;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class TileSheetToCompactTileSheetConverter: public keel::Converter<TileSheet, CompactTileSheet> {
 | 
			
		||||
	ox::Error convert(keel::Context*, TileSheet *src, CompactTileSheet *dst) const noexcept final;
 | 
			
		||||
	ox::Error convert(keel::Context&, TileSheet &src, CompactTileSheet &dst) const noexcept final;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class TileSheetV2ToTileSheetConverter: public keel::Converter<TileSheetV2, TileSheet> {
 | 
			
		||||
	static void convertSubsheet(
 | 
			
		||||
			TileSheetV2::SubSheet *src,
 | 
			
		||||
			TileSheet::SubSheet *dst,
 | 
			
		||||
			SubSheetId *idIt) noexcept;
 | 
			
		||||
			TileSheetV2::SubSheet &src,
 | 
			
		||||
			TileSheet::SubSheet &dst,
 | 
			
		||||
			SubSheetId &idIt) noexcept;
 | 
			
		||||
 | 
			
		||||
	ox::Error convert(keel::Context*, TileSheetV2 *src, TileSheet *dst) const noexcept final;
 | 
			
		||||
	ox::Error convert(keel::Context&, TileSheetV2 &src, TileSheet &dst) const noexcept final;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -436,8 +436,8 @@ ox::Error loadBgTileSheet(
 | 
			
		||||
		ox::FileAddress const&paletteAddr) noexcept {
 | 
			
		||||
	auto &gctx = glctx(*ctx);
 | 
			
		||||
	auto &kctx = gctx.turbineCtx.keelCtx;
 | 
			
		||||
	oxRequire(tilesheet, readObj<CompactTileSheet>(&kctx, tilesheetAddr));
 | 
			
		||||
	oxRequire(palette, readObj<Palette>(&kctx, paletteAddr ? paletteAddr : tilesheet->defaultPalette));
 | 
			
		||||
	oxRequire(tilesheet, readObj<CompactTileSheet>(kctx, tilesheetAddr));
 | 
			
		||||
	oxRequire(palette, readObj<Palette>(kctx, paletteAddr ? paletteAddr : tilesheet->defaultPalette));
 | 
			
		||||
	oxRequire(tsd, loadTileSheet(*ctx, *tilesheet).to([](TileSheetData const&t) -> TileSheetData {
 | 
			
		||||
		return {
 | 
			
		||||
			.pixels = resizeTileSheetData(t.pixels, t.size(), Scale),
 | 
			
		||||
@@ -456,8 +456,8 @@ ox::Error loadSpriteTileSheet(
 | 
			
		||||
		ox::FileAddress const&paletteAddr) noexcept {
 | 
			
		||||
	auto &gctx = glctx(*ctx);
 | 
			
		||||
	auto &kctx = gctx.turbineCtx.keelCtx;
 | 
			
		||||
	oxRequire(tilesheet, readObj<CompactTileSheet>(&kctx, tilesheetAddr));
 | 
			
		||||
	oxRequire(palette, readObj<Palette>(&kctx, paletteAddr ? paletteAddr : tilesheet->defaultPalette));
 | 
			
		||||
	oxRequire(tilesheet, readObj<CompactTileSheet>(kctx, tilesheetAddr));
 | 
			
		||||
	oxRequire(palette, readObj<Palette>(kctx, paletteAddr ? paletteAddr : tilesheet->defaultPalette));
 | 
			
		||||
	oxRequire(tsd, loadTileSheet(*ctx, *tilesheet));
 | 
			
		||||
	renderer::loadSpriteTexture(gctx, tsd.pixels.data(), tsd.width, tsd.height);
 | 
			
		||||
	renderer::loadSpritePalette(gctx, *palette);
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ PaletteEditorImGui::PaletteEditorImGui(turbine::Context *ctx, ox::String path):
 | 
			
		||||
	m_ctx(ctx),
 | 
			
		||||
	m_itemPath(std::move(path)),
 | 
			
		||||
	m_itemName(m_itemPath.substr(std::find(m_itemPath.rbegin(), m_itemPath.rend(), '/').offset() + 1)),
 | 
			
		||||
	m_pal(*keel::readObj<Palette>(&m_ctx->keelCtx, ox::FileAddress(m_itemPath.c_str())).unwrapThrow()) {
 | 
			
		||||
	m_pal(*keel::readObj<Palette>(m_ctx->keelCtx, ox::FileAddress(m_itemPath.c_str())).unwrapThrow()) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ox::String &PaletteEditorImGui::itemName() const noexcept {
 | 
			
		||||
 
 | 
			
		||||
@@ -566,10 +566,10 @@ class PaletteChangeCommand: public TileSheetCommand {
 | 
			
		||||
TileSheetEditorModel::TileSheetEditorModel(turbine::Context *ctx, ox::String path):
 | 
			
		||||
	m_ctx(ctx),
 | 
			
		||||
	m_path(std::move(path)) {
 | 
			
		||||
	oxRequireT(img, readObj<TileSheet>(&ctx->keelCtx, m_path));
 | 
			
		||||
	oxRequireT(img, readObj<TileSheet>(ctx->keelCtx, m_path));
 | 
			
		||||
	m_img = *img;
 | 
			
		||||
	if (m_img.defaultPalette) {
 | 
			
		||||
		oxThrowError(readObj<Palette>(&ctx->keelCtx, m_img.defaultPalette).moveTo(&m_pal));
 | 
			
		||||
		oxThrowError(readObj<Palette>(ctx->keelCtx, m_img.defaultPalette).moveTo(&m_pal));
 | 
			
		||||
	}
 | 
			
		||||
	m_pal.updated.connect(this, &TileSheetEditorModel::markUpdated);
 | 
			
		||||
	m_undoStack.changeTriggered.connect(this, &TileSheetEditorModel::markUpdatedCmdId);
 | 
			
		||||
@@ -752,7 +752,7 @@ ox::Error TileSheetEditorModel::markUpdatedCmdId(const studio::UndoCommand *cmd)
 | 
			
		||||
	m_updated = true;
 | 
			
		||||
	const auto cmdId = cmd->commandId();
 | 
			
		||||
	if (static_cast<CommandId>(cmdId) == CommandId::PaletteChange) {
 | 
			
		||||
		oxReturnError(readObj<Palette>(&m_ctx->keelCtx, ox::StringView(m_img.defaultPalette.getPath().value)).moveTo(&m_pal));
 | 
			
		||||
		oxReturnError(readObj<Palette>(m_ctx->keelCtx, ox::StringView(m_img.defaultPalette.getPath().value)).moveTo(&m_pal));
 | 
			
		||||
	}
 | 
			
		||||
	auto tsCmd = dynamic_cast<const TileSheetCommand*>(cmd);
 | 
			
		||||
	auto idx = m_img.validateSubSheetIdx(tsCmd->subsheetIdx());
 | 
			
		||||
 
 | 
			
		||||
@@ -34,20 +34,20 @@ constexpr void setLayerAttachments(unsigned layer, const TileDoc &srcTile, Scene
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ox::Error SceneDocToSceneStaticConverter::convert(
 | 
			
		||||
		keel::Context *ctx,
 | 
			
		||||
		SceneDoc *src,
 | 
			
		||||
		SceneStatic *dst) const noexcept {
 | 
			
		||||
	oxRequire(ts, keel::readObj<core::TileSheet>(ctx, src->tilesheet));
 | 
			
		||||
	const auto layerCnt = src->tiles.size();
 | 
			
		||||
	dst->setLayerCnt(layerCnt);
 | 
			
		||||
	dst->tilesheet = ox::FileAddress(src->tilesheet);
 | 
			
		||||
	dst->palettes.reserve(src->palettes.size());
 | 
			
		||||
	for (const auto &pal : src->palettes) {
 | 
			
		||||
		dst->palettes.emplace_back(pal);
 | 
			
		||||
		keel::Context &ctx,
 | 
			
		||||
		SceneDoc &src,
 | 
			
		||||
		SceneStatic &dst) const noexcept {
 | 
			
		||||
	oxRequire(ts, keel::readObj<core::TileSheet>(ctx, src.tilesheet));
 | 
			
		||||
	const auto layerCnt = src.tiles.size();
 | 
			
		||||
	dst.setLayerCnt(layerCnt);
 | 
			
		||||
	dst.tilesheet = ox::FileAddress(src.tilesheet);
 | 
			
		||||
	dst.palettes.reserve(src.palettes.size());
 | 
			
		||||
	for (const auto &pal : src.palettes) {
 | 
			
		||||
		dst.palettes.emplace_back(pal);
 | 
			
		||||
	}
 | 
			
		||||
	for (auto layerIdx = 0u; const auto &layer : src->tiles) {
 | 
			
		||||
		const auto layerDim = src->size(layerIdx);
 | 
			
		||||
		auto dstLayer = dst->layer(layerIdx);
 | 
			
		||||
	for (auto layerIdx = 0u; const auto &layer : src.tiles) {
 | 
			
		||||
		const auto layerDim = src.size(layerIdx);
 | 
			
		||||
		auto dstLayer = dst.layer(layerIdx);
 | 
			
		||||
		dstLayer.setDimensions(layerDim);
 | 
			
		||||
		for (auto tileIdx = 0u; const auto &row : layer) {
 | 
			
		||||
			for (const auto &srcTile : row) {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
namespace nostalgia::scene {
 | 
			
		||||
 | 
			
		||||
class SceneDocToSceneStaticConverter: public keel::Converter<SceneDoc, SceneStatic> {
 | 
			
		||||
	ox::Error convert(keel::Context*, SceneDoc *src, SceneStatic *dst) const noexcept final;
 | 
			
		||||
	ox::Error convert(keel::Context&, SceneDoc &src, SceneStatic &dst) const noexcept final;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ namespace nostalgia::scene {
 | 
			
		||||
 | 
			
		||||
SceneEditor::SceneEditor(turbine::Context *ctx, ox::CRStringView path) {
 | 
			
		||||
	m_ctx = ctx;
 | 
			
		||||
	oxRequireT(scn, keel::readObj<SceneStatic>(&m_ctx->keelCtx, path));
 | 
			
		||||
	oxRequireT(scn, keel::readObj<SceneStatic>(m_ctx->keelCtx, path));
 | 
			
		||||
	m_scene = *scn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ ox::Error run(ox::UniquePtr<ox::FileSystem> &&fs) noexcept {
 | 
			
		||||
	oxRequireM(tctx, turbine::init(std::move(fs), "Nostalgia"));
 | 
			
		||||
	oxRequireM(cctx, core::init(tctx.get()));
 | 
			
		||||
	constexpr ox::FileAddress SceneAddr("/Scenes/Chester.nscn");
 | 
			
		||||
	oxRequire(scn, keel::readObj<scene::SceneStatic>(&tctx->keelCtx, SceneAddr));
 | 
			
		||||
	oxRequire(scn, keel::readObj<scene::SceneStatic>(tctx->keelCtx, SceneAddr));
 | 
			
		||||
	turbine::setUpdateHandler(*tctx, updateHandler);
 | 
			
		||||
	turbine::setKeyEventHandler(*tctx, keyEventHandler);
 | 
			
		||||
	s_scene.emplace(*scn);
 | 
			
		||||
 
 | 
			
		||||
@@ -303,7 +303,7 @@ void StudioUI::save() noexcept {
 | 
			
		||||
 | 
			
		||||
ox::Error StudioUI::openProject(ox::CRStringView path) noexcept {
 | 
			
		||||
	oxRequireM(fs, keel::loadRomFs(path));
 | 
			
		||||
	oxReturnError(keel::setRomFs(&m_ctx->keelCtx, std::move(fs)));
 | 
			
		||||
	oxReturnError(keel::setRomFs(m_ctx->keelCtx, std::move(fs)));
 | 
			
		||||
	turbine::setWindowTitle(*m_ctx, ox::sfmt("{} - {}", m_ctx->keelCtx.appName, path));
 | 
			
		||||
	m_project = ox::make_unique<studio::Project>(m_ctx->keelCtx, ox::String(path), m_projectDir);
 | 
			
		||||
	auto sctx = applicationData<studio::StudioContext>(*m_ctx);
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,7 @@ class ItemMakerT: public ItemMaker {
 | 
			
		||||
		ox::Error write(turbine::Context *ctx, ox::CRStringView pName) const noexcept override {
 | 
			
		||||
			const auto path = ox::sfmt("/{}/{}.{}", parentDir, pName, fileExt);
 | 
			
		||||
			auto sctx = turbine::applicationData<studio::StudioContext>(*ctx);
 | 
			
		||||
			keel::createUuidMapping(&ctx->keelCtx, path, ox::UUID::generate().unwrap());
 | 
			
		||||
			keel::createUuidMapping(ctx->keelCtx, path, ox::UUID::generate().unwrap());
 | 
			
		||||
			return sctx->project->writeObj(path, item, fmt);
 | 
			
		||||
		}
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@ ox::Error Project::writeObj(ox::CRStringView path, T const&obj, ox::ClawFormat f
 | 
			
		||||
		const auto typePath = ox::sfmt("/{}/{}", descPath, buildTypeId(*t));
 | 
			
		||||
		oxReturnError(writeBuff(typePath, typeOut));
 | 
			
		||||
	}
 | 
			
		||||
	oxReturnError(keel::setAsset(&m_ctx, path, obj));
 | 
			
		||||
	oxReturnError(keel::setAsset(m_ctx, path, obj));
 | 
			
		||||
	fileUpdated.emit(path);
 | 
			
		||||
	return {};
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ static ox::Result<std::size_t> findPreloadSection() noexcept {
 | 
			
		||||
 | 
			
		||||
ox::Result<ox::UniquePtr<turbine::Context>> init(ox::UPtr<ox::FileSystem> fs, ox::CRStringView appName) noexcept {
 | 
			
		||||
	auto ctx = ox::make_unique<gba::Context>();
 | 
			
		||||
	oxReturnError(keel::init(&ctx->keelCtx, std::move(fs), appName));
 | 
			
		||||
	oxReturnError(keel::init(ctx->keelCtx, std::move(fs), appName));
 | 
			
		||||
#ifdef OX_BARE_METAL
 | 
			
		||||
	oxReturnError(findPreloadSection().moveTo(&ctx->keelCtx.preloadSectionOffset));
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ static void draw(GLFWwindow *window, int, int) noexcept {
 | 
			
		||||
 | 
			
		||||
ox::Result<ox::UPtr<Context>> init(ox::UPtr<ox::FileSystem> fs, ox::CRStringView appName) noexcept {
 | 
			
		||||
	auto ctx = ox::make_unique<GlfwContext>();
 | 
			
		||||
	oxReturnError(keel::init(&ctx->keelCtx, std::move(fs), appName));
 | 
			
		||||
	oxReturnError(keel::init(ctx->keelCtx, std::move(fs), appName));
 | 
			
		||||
	using namespace std::chrono;
 | 
			
		||||
	ctx->startTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
 | 
			
		||||
	glfwInit();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user