[nostalgia/gfx/studio] Make TileSheetEditor use export-tilesheet functions for export, fix exporting Root subsheet
All checks were successful
Build / build (push) Successful in 1m18s

This commit is contained in:
2025-07-24 01:45:27 -05:00
parent 0c866d1b96
commit 51f2905c9c
3 changed files with 43 additions and 85 deletions

View File

@ -14,6 +14,7 @@
#include "export-tilesheet.hpp"
#include "nostalgia/gfx/tilesheet.hpp"
#include "studio/context.hpp"
@ -71,6 +72,32 @@ static ox::Error toPngFile(
8)));
}
ox::Error exportSubsheetToPng(
TileSheet::SubSheet const &s,
Palette const &pal,
size_t const palPage,
ox::CStringViewCR dstPath,
int const scale) noexcept {
// subsheet to png
auto const width = s.columns * TileWidth;
auto const height = s.rows * TileHeight;
auto const err = toPngFile(
dstPath,
normalizePixelArrangement(
normalizePixelSizes(s.pixels),
s.columns,
scale),
pal,
palPage,
static_cast<unsigned>(width * scale),
static_cast<unsigned>(height * scale));
if (err) {
oxErrorf("TileSheet export failed: {}", toStr(err));
return ox::Error{7, "TileSheet export failed"};
}
return {};
}
ox::Error exportSubsheetToPng(
TileSheet const &src,
Palette const &pal,
@ -84,23 +111,12 @@ ox::Error exportSubsheetToPng(
if (ssErr) {
return ox::Error{6, "failed to find SubSheet"};
}
auto const width = s->columns * TileWidth;
auto const height = s->rows * TileHeight;
auto const err = toPngFile(
dstPath,
normalizePixelArrangement(
normalizePixelSizes(s->pixels),
s->columns,
scale),
pal,
palPage,
static_cast<unsigned>(width * scale),
static_cast<unsigned>(height * scale));
if (err) {
oxErrorf("TileSheet export failed: {}", toStr(err));
return ox::Error{7, "TileSheet export failed"};
}
return {};
return exportSubsheetToPng(
*s,
pal,
palPage,
dstPath,
scale);
}
ox::Error cmdExportTilesheet(studio::Project &project, ox::SpanView<ox::CString> const args) noexcept {
@ -120,7 +136,7 @@ ox::Error cmdExportTilesheet(studio::Project &project, ox::SpanView<ox::CString>
OX_REQUIRE(srcPath, clargs.getString("src-path").transformError(1, "no src path specified"));
OX_REQUIRE(dstPath, clargs.getString("dst-path").transformError(2, "no dst path specified"));
auto const palPath = clargs.getString("pal-path", "");
auto const subsheetPath = clargs.getString("subsheet-path").or_value({});
auto const subsheetPath = clargs.getString("subsheet-path").or_value(ox::String{"Root"});
auto const palPage = static_cast<size_t>(clargs.getInt("pal-page", 0));
auto const scale = clargs.getInt("scale", 1);
showUsage = false;

View File

@ -8,6 +8,13 @@
namespace nostalgia::gfx {
ox::Error exportSubsheetToPng(
TileSheet::SubSheet const &s,
Palette const &pal,
size_t palPage,
ox::CStringViewCR dstPath,
int scale) noexcept;
ox::Error exportSubsheetToPng(
TileSheet const &src,
Palette const &pal,

View File

@ -11,6 +11,7 @@
#include <nostalgia/gfx/studio.hpp>
#include "../subcommands/export-tilesheet/export-tilesheet.hpp"
#include "tilesheeteditor-imgui.hpp"
namespace nostalgia::gfx {
@ -37,58 +38,6 @@ OX_MODEL_BEGIN(TileSheetEditorConfig)
OX_MODEL_FIELD_RENAME(activeSubsheet, active_subsheet)
OX_MODEL_END()
static ox::Vector<uint32_t> normalizePixelSizes(
ox::Vector<uint8_t> const &inPixels) noexcept {
ox::Vector<uint32_t> outPixels;
outPixels.reserve(inPixels.size());
outPixels.resize(inPixels.size());
for (std::size_t i = 0; i < inPixels.size(); ++i) {
outPixels[i] = inPixels[i];
}
return outPixels;
}
static ox::Vector<uint32_t> normalizePixelArrangement(
ox::Vector<uint32_t> const &inPixels,
int const cols,
int const scale) {
auto const scalePt = ox::Point{scale, scale};
auto const width = cols * TileWidth;
auto const height = static_cast<int>(inPixels.size()) / width;
auto const dstWidth = width * scale;
ox::Vector<uint32_t> outPixels(static_cast<size_t>((width * scale) * (height * scale)));
for (std::size_t dstIdx = 0; dstIdx < outPixels.size(); ++dstIdx) {
auto const dstPt = ox::Point{
static_cast<int>(dstIdx) % dstWidth,
static_cast<int>(dstIdx) / dstWidth};
auto const srcPt = dstPt / scalePt;
auto const srcIdx = ptToIdx(srcPt, cols);
outPixels[dstIdx] = inPixels[srcIdx];
}
return outPixels;
}
static ox::Error toPngFile(
ox::CStringViewCR path,
ox::Vector<uint32_t> &&pixels,
Palette const &pal,
size_t const page,
unsigned const width,
unsigned const height) noexcept {
for (auto &c : pixels) {
c = color32(color(pal, page, c)) | static_cast<Color32>(0XFF << 24);
}
constexpr auto fmt = LCT_RGBA;
return ox::Error(static_cast<ox::ErrorCode>(
lodepng_encode_file(
path.c_str(),
reinterpret_cast<uint8_t const*>(pixels.data()),
width,
height,
fmt,
8)));
}
TileSheetEditorImGui::TileSheetEditorImGui(studio::Context &sctx, ox::StringParam path):
Editor{sctx, std::move(path)},
m_sctx{sctx},
@ -421,21 +370,7 @@ ox::Error TileSheetEditorImGui::exportSubsheetToPng(int const scale) const noexc
// subsheet to png
auto const &s = m_model.activeSubSheet();
auto const &pal = m_model.pal();
auto const width = s.columns * TileWidth;
auto const height = s.rows * TileHeight;
auto pixels = normalizePixelSizes(s.pixels);
pixels = normalizePixelArrangement(pixels, s.columns, scale);
auto const err = toPngFile(
path,
std::move(pixels),
pal,
m_model.palettePage(),
static_cast<unsigned>(width * scale),
static_cast<unsigned>(height * scale));
if (err) {
oxErrorf("TileSheet export failed: {}", toStr(err));
}
return err;
return gfx::exportSubsheetToPng(s, pal, m_model.palettePage(), path, scale);
}
void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const &fbSize) noexcept {