From c36b244dd30e6f8e4dfa3a305e42c469b591a09e Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 21 Jan 2025 22:17:13 -0600 Subject: [PATCH] [nostalgia/gfx] Cleanup, add PaletteV5, restore mistakenly removed function --- .../gfx/include/nostalgia/gfx/palette.hpp | 106 +++++++++++++++--- .../gfx/include/nostalgia/gfx/tilesheet.hpp | 30 +---- .../modules/gfx/src/keel/keelmodule.cpp | 9 +- .../modules/gfx/src/keel/typeconv.cpp | 30 ++++- .../modules/gfx/src/keel/typeconv.hpp | 13 ++- .../paletteeditor/paletteeditor-imgui.cpp | 2 +- .../tilesheeteditor/tilesheeteditormodel.cpp | 2 +- .../tilesheeteditor/tilesheetpixels.cpp | 5 +- src/nostalgia/modules/gfx/src/tilesheet.cpp | 43 ++----- 9 files changed, 149 insertions(+), 91 deletions(-) diff --git a/src/nostalgia/modules/gfx/include/nostalgia/gfx/palette.hpp b/src/nostalgia/modules/gfx/include/nostalgia/gfx/palette.hpp index c5e0ff8d..5a832068 100644 --- a/src/nostalgia/modules/gfx/include/nostalgia/gfx/palette.hpp +++ b/src/nostalgia/modules/gfx/include/nostalgia/gfx/palette.hpp @@ -33,7 +33,31 @@ OX_MODEL_BEGIN(PaletteColorV1) OX_MODEL_FIELD(a) OX_MODEL_END() -using PaletteColor = PaletteColorV1; + +struct PaletteColorV2 { + static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.PaletteColor"; + static constexpr auto TypeVersion = 2; + uint8_t r{}, g{}, b{}, a{}; + constexpr PaletteColorV2() noexcept = default; + constexpr PaletteColorV2(Color16 const c) noexcept: + r{red16(c)}, + g{green16(c)}, + b{blue16(c)}, + a{alpha16(c)} {} + constexpr PaletteColorV2(uint8_t const r, uint8_t const g, uint8_t const b, uint8_t const a) noexcept: + r{r}, g{g}, b{b}, a{a} {} + constexpr operator Color16() const noexcept { return color16(r, g, b, a); } +}; + +OX_MODEL_BEGIN(PaletteColorV2) + OX_MODEL_FIELD(r) + OX_MODEL_FIELD(g) + OX_MODEL_FIELD(b) + OX_MODEL_FIELD(a) +OX_MODEL_END() + + +using PaletteColor = PaletteColorV2; struct PalettePageV1 { @@ -58,7 +82,31 @@ OX_MODEL_BEGIN(PalettePageV1) OX_MODEL_FIELD(colors) OX_MODEL_END() -using PalettePage = PalettePageV1; + +struct PalettePageV2 { + static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.Palette.PalettePage"; + static constexpr auto TypeVersion = 2; + ox::String name; + ox::Vector colors; + constexpr PalettePageV2() noexcept = default; + constexpr PalettePageV2(ox::StringParam pName, ox::Vector pColors) noexcept: + name(std::move(pName)), colors(std::move(pColors)) {} + constexpr PalettePageV2(ox::StringParam pName, ox::Vector const&pColors) noexcept: + name(std::move(pName)) { + colors.reserve(pColors.size()); + for (auto const c : pColors) { + colors.emplace_back(c); + } + } +}; + +OX_MODEL_BEGIN(PalettePageV2) + OX_MODEL_FIELD(name) + OX_MODEL_FIELD(colors) +OX_MODEL_END() + + +using PalettePage = PalettePageV2; struct NostalgiaPalette { @@ -166,11 +214,41 @@ constexpr ox::Error repair(PaletteV4 &p) noexcept { } -using Palette = PaletteV4; +struct PaletteV5 { + static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.Palette"; + static constexpr auto TypeVersion = 5; + static constexpr auto Preloadable = true; + ox::Vector colorNames; + ox::Vector pages; +}; + +OX_MODEL_BEGIN(PaletteV5) + OX_MODEL_FIELD(colorNames) + OX_MODEL_FIELD(pages) +OX_MODEL_END() + +[[nodiscard]] +constexpr bool valid(PaletteV5 const&p) noexcept { + auto const colors = p.colorNames.size(); + return ox::all_of(p.pages.begin(), p.pages.end(), [colors](PalettePageV2 const&page) { + return page.colors.size() == colors; + }); +} + +constexpr ox::Error repair(PaletteV5 &p) noexcept { + auto const colors = p.colorNames.size(); + for (auto &page : p.pages) { + page.colors.resize(colors); + } + return {}; +} + + +using Palette = PaletteV5; struct CompactPaletteV1 { - static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.CompactPalette"; + static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.CompactPalette"; static constexpr auto TypeVersion = 1; static constexpr auto Preloadable = true; ox::Vector> pages{}; @@ -207,7 +285,7 @@ using CompactPalette = CompactPaletteV1; [[nodiscard]] -constexpr Color16 color(Palette const&pal, size_t page, size_t idx) noexcept { +constexpr Color16 color(Palette const&pal, size_t const page, size_t const idx) noexcept { if (page < pal.pages.size() && idx < pal.pages[page].colors.size()) [[likely]] { return pal.pages[page].colors[idx]; } @@ -215,7 +293,7 @@ constexpr Color16 color(Palette const&pal, size_t page, size_t idx) noexcept { } [[nodiscard]] -constexpr Color16 color(CompactPalette const&pal, size_t page, size_t idx) noexcept { +constexpr Color16 color(CompactPalette const&pal, size_t const page, size_t const idx) noexcept { if (page < pal.pages.size() && idx < pal.pages[page].size()) [[likely]] { return pal.pages[page][idx]; } @@ -223,37 +301,37 @@ constexpr Color16 color(CompactPalette const&pal, size_t page, size_t idx) noexc } [[nodiscard]] -constexpr Color16 color(Palette const&pal, size_t idx) noexcept { +constexpr Color16 color(Palette const&pal, size_t const idx) noexcept { return color(pal, 0, idx); } [[nodiscard]] -constexpr Color16 color(CompactPalette const&pal, size_t idx) noexcept { +constexpr Color16 color(CompactPalette const&pal, size_t const idx) noexcept { return color(pal, 0, idx); } [[nodiscard]] -constexpr auto &colors(Palette &pal, size_t page = 0) noexcept { +constexpr auto &colors(Palette &pal, size_t const page = 0) noexcept { return pal.pages[page].colors; } [[nodiscard]] -constexpr auto &colors(CompactPalette &pal, size_t page = 0) noexcept { +constexpr auto &colors(CompactPalette &pal, size_t const page = 0) noexcept { return pal.pages[page]; } [[nodiscard]] -constexpr auto &colors(Palette const&pal, size_t page = 0) noexcept { +constexpr auto &colors(Palette const&pal, size_t const page = 0) noexcept { return pal.pages[page]; } [[nodiscard]] -constexpr auto &colors(CompactPalette const&pal, size_t page = 0) noexcept { +constexpr auto &colors(CompactPalette const&pal, size_t const page = 0) noexcept { return pal.pages[page]; } [[nodiscard]] -constexpr size_t colorCnt(Palette const&pal, size_t page = 0) noexcept { +constexpr size_t colorCnt(Palette const&pal, size_t const page = 0) noexcept { if (page < pal.pages.size()) [[likely]] { return pal.pages[page].colors.size(); } @@ -261,7 +339,7 @@ constexpr size_t colorCnt(Palette const&pal, size_t page = 0) noexcept { } [[nodiscard]] -constexpr size_t colorCnt(CompactPalette const&pal, size_t page = 0) noexcept { +constexpr size_t colorCnt(CompactPalette const&pal, size_t const page = 0) noexcept { if (page < pal.pages.size()) [[likely]] { return pal.pages[page].size(); } diff --git a/src/nostalgia/modules/gfx/include/nostalgia/gfx/tilesheet.hpp b/src/nostalgia/modules/gfx/include/nostalgia/gfx/tilesheet.hpp index d2e5a575..176fe39e 100644 --- a/src/nostalgia/modules/gfx/include/nostalgia/gfx/tilesheet.hpp +++ b/src/nostalgia/modules/gfx/include/nostalgia/gfx/tilesheet.hpp @@ -400,30 +400,12 @@ TileSheet::SubSheet const*getSubsheet(TileSheet const&ts, SubSheetId id) noexcep [[nodiscard]] ox::Optional getTileIdx(TileSheet const&ts, SubSheetId id) noexcept; -[[nodiscard]] -uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept; - -[[nodiscard]] -uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, std::size_t idx) noexcept; - [[nodiscard]] uint8_t getPixel(TileSheet::SubSheet const&ss, std::size_t idx) noexcept; -[[nodiscard]] -uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; - -[[nodiscard]] -uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; - [[nodiscard]] uint8_t getPixel(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept; -constexpr void walkPixels(TileSheet::SubSheet const&ss, int8_t, auto callback) noexcept { - for (std::size_t i = 0; i < ss.pixels.size(); ++i) { - callback(i, ss.pixels[i]); - } -} - void setPixel(TileSheet::SubSheet &ss, ox::Point const&pt, uint8_t palIdx) noexcept; ox::Error setPixelCount(TileSheet::SubSheet &ss, std::size_t cnt) noexcept; @@ -438,7 +420,6 @@ unsigned pixelCnt(TileSheet::SubSheet const&ss) noexcept; /** * * @param ss - * @param pBpp * @param sz size of Subsheet in tiles (not pixels) */ ox::Error resizeSubsheet(TileSheet::SubSheet &ss, ox::Size const&sz) noexcept; @@ -447,6 +428,7 @@ ox::Error resizeSubsheet(TileSheet::SubSheet &ss, ox::Size const&sz) noexcept; * validateSubSheetIdx takes a SubSheetIdx and moves the index to the * preceding or parent sheet if the current corresponding sheet does * not exist. + * @param ts * @param idx SubSheetIdx to validate and correct * @return a valid version of idx */ @@ -482,13 +464,7 @@ ox::Error rmSubSheet( ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept; [[nodiscard]] -uint8_t getPixel4Bpp( - TileSheet const&ts, - ox::Point const&pt, - TileSheet::SubSheetIdx const&subsheetIdx) noexcept; - -[[nodiscard]] -uint8_t getPixel8Bpp( +uint8_t getPixel( TileSheet const&ts, ox::Point const&pt, TileSheet::SubSheetIdx const&subsheetIdx) noexcept; @@ -508,7 +484,7 @@ ox::Vector pixels(TileSheet &ts) noexcept; struct CompactTileSheetV1 { - static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.CompactTileSheet"; + static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.CompactTileSheet"; static constexpr auto TypeVersion = 1; static constexpr auto Preloadable = true; int8_t bpp = 0; diff --git a/src/nostalgia/modules/gfx/src/keel/keelmodule.cpp b/src/nostalgia/modules/gfx/src/keel/keelmodule.cpp index 6148fc51..63f1fd89 100644 --- a/src/nostalgia/modules/gfx/src/keel/keelmodule.cpp +++ b/src/nostalgia/modules/gfx/src/keel/keelmodule.cpp @@ -19,6 +19,7 @@ static class: public keel::Module { PaletteV1ToPaletteV2Converter m_paletteV1ToPaletteV2Converter; PaletteV2ToPaletteV3Converter m_paletteV2ToPaletteV3Converter; PaletteV3ToPaletteV4Converter m_paletteV3ToPaletteV4Converter; + PaletteV4ToPaletteV5Converter m_paletteV4ToPaletteV5Converter; PaletteToCompactPaletteConverter m_paletteToCompactPaletteConverter; TileSheetV1ToTileSheetV2Converter m_tileSheetV1ToTileSheetV2Converter; TileSheetV2ToTileSheetV3Converter m_tileSheetV2ToTileSheetV3Converter; @@ -45,6 +46,7 @@ static class: public keel::Module { keel::generateTypeDesc, keel::generateTypeDesc, keel::generateTypeDesc, + keel::generateTypeDesc, keel::generateTypeDesc, }; } @@ -56,6 +58,7 @@ static class: public keel::Module { &m_paletteV1ToPaletteV2Converter, &m_paletteV2ToPaletteV3Converter, &m_paletteV3ToPaletteV4Converter, + &m_paletteV4ToPaletteV5Converter, &m_paletteToCompactPaletteConverter, &m_tileSheetV1ToTileSheetV2Converter, &m_tileSheetV2ToTileSheetV3Converter, @@ -73,7 +76,8 @@ static class: public keel::Module { if (typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || - typeId == ox::ModelTypeId_v) { + typeId == ox::ModelTypeId_v || + typeId == ox::ModelTypeId_v) { OX_RETURN_ERROR(keel::convertBuffToBuff( ctx, buff, ox::ClawFormat::Metal).moveTo(buff)); return true; @@ -85,7 +89,8 @@ static class: public keel::Module { typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || typeId == ox::ModelTypeId_v || - typeId == ox::ModelTypeId_v) { + typeId == ox::ModelTypeId_v || + typeId == ox::ModelTypeId_v) { OX_RETURN_ERROR(keel::convertBuffToBuff( ctx, buff, ox::ClawFormat::Metal).moveTo(buff)); return true; diff --git a/src/nostalgia/modules/gfx/src/keel/typeconv.cpp b/src/nostalgia/modules/gfx/src/keel/typeconv.cpp index 28fc142d..e3b20569 100644 --- a/src/nostalgia/modules/gfx/src/keel/typeconv.cpp +++ b/src/nostalgia/modules/gfx/src/keel/typeconv.cpp @@ -52,6 +52,26 @@ ox::Error PaletteV3ToPaletteV4Converter::convert( return {}; } +ox::Error PaletteV4ToPaletteV5Converter::convert( + keel::Context&, + PaletteV4 &src, + PaletteV5 &dst) const noexcept { + dst.colorNames = std::move(src.colorNames); + dst.pages.reserve(src.pages.size()); + for (auto &s : src.pages) { + ox::Vector colors; + colors.reserve(s.colors.size()); + for (auto const&c : s.colors) { + colors.emplace_back(c.r, c.g, c.b, c.a); + } + dst.pages.emplace_back(PalettePageV2{ + std::move(s.name), + std::move(colors), + }); + } + return {}; +} + ox::Error PaletteToCompactPaletteConverter::convert( keel::Context&, Palette &src, @@ -137,9 +157,8 @@ ox::Error TileSheetV3ToTileSheetV4Converter::convert( void TileSheetV4ToTileSheetV5Converter::convertSubsheet( int const bpp, TileSheetV4::SubSheet &src, - TileSheetV5::SubSheet &dst, - SubSheetId &idIt) noexcept { - dst.id = idIt; + TileSheetV5::SubSheet &dst) noexcept { + dst.id = src.id; dst.name = std::move(src.name); dst.columns = src.columns; dst.rows = src.rows; @@ -154,10 +173,9 @@ void TileSheetV4ToTileSheetV5Converter::convertSubsheet( } else { dst.pixels = std::move(src.pixels); } - ++idIt; dst.subsheets.resize(src.subsheets.size()); for (auto i = 0u; i < src.subsheets.size(); ++i) { - convertSubsheet(bpp, src.subsheets[i], dst.subsheets[i], idIt); + convertSubsheet(bpp, src.subsheets[i], dst.subsheets[i]); } } @@ -168,7 +186,7 @@ ox::Error TileSheetV4ToTileSheetV5Converter::convert( dst.bpp = src.bpp; dst.idIt = src.idIt; dst.defaultPalette = std::move(src.defaultPalette); - convertSubsheet(dst.bpp, src.subsheet, dst.subsheet, dst.idIt); + convertSubsheet(dst.bpp, src.subsheet, dst.subsheet); return {}; } diff --git a/src/nostalgia/modules/gfx/src/keel/typeconv.hpp b/src/nostalgia/modules/gfx/src/keel/typeconv.hpp index a5b7664d..101eafa0 100644 --- a/src/nostalgia/modules/gfx/src/keel/typeconv.hpp +++ b/src/nostalgia/modules/gfx/src/keel/typeconv.hpp @@ -21,15 +21,19 @@ class NostalgiaPaletteToPaletteV1Converter: public keel::Converter { - ox::Error convert(keel::Context&, PaletteV1 &src, PaletteV2 &dst) const noexcept final; + ox::Error convert(keel::Context&, PaletteV1 &src, PaletteV2 &dst) const noexcept final; }; class PaletteV2ToPaletteV3Converter: public keel::Converter { - ox::Error convert(keel::Context&, PaletteV2 &src, PaletteV3 &dst) const noexcept final; + ox::Error convert(keel::Context&, PaletteV2 &src, PaletteV3 &dst) const noexcept final; }; class PaletteV3ToPaletteV4Converter: public keel::Converter { - ox::Error convert(keel::Context&, PaletteV3 &src, PaletteV4 &dst) const noexcept final; + ox::Error convert(keel::Context&, PaletteV3 &src, PaletteV4 &dst) const noexcept final; +}; + +class PaletteV4ToPaletteV5Converter: public keel::Converter { + ox::Error convert(keel::Context&, PaletteV4 &src, PaletteV5 &dst) const noexcept final; }; class PaletteToCompactPaletteConverter: public keel::Converter { @@ -60,8 +64,7 @@ class TileSheetV4ToTileSheetV5Converter final: public keel::Converter( m_pal, m_page, m_selectedColorRow); } - if (ig::mainWinHasFocus()) { + if (ig::mainWinHasFocus() && !inputFocused) { if (!ImGui::IsKeyDown(ImGuiKey_ModAlt)) { numShortcuts(m_selectedColorRow, largestPage(m_pal)); } else { diff --git a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp index 4a5117f7..00e603c0 100644 --- a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp +++ b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp @@ -282,7 +282,7 @@ void TileSheetEditorModel::ackUpdate() noexcept { } ox::Error TileSheetEditorModel::saveFile() noexcept { - return m_sctx.project->writeObj(m_path, m_img, ox::ClawFormat::Metal); + return m_sctx.project->writeObj(m_path, m_img, ox::ClawFormat::Organic); } bool TileSheetEditorModel::pixelSelected(std::size_t const idx) const noexcept { diff --git a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheetpixels.cpp b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheetpixels.cpp index a594e320..22a01943 100644 --- a/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheetpixels.cpp +++ b/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheetpixels.cpp @@ -131,7 +131,8 @@ void TileSheetPixels::setBufferObjects(ox::Vec2 const&paneSize) noexcept { m_bufferSet.vertices.resize(pixels * vboLen); m_bufferSet.elements.resize(pixels * VertexEboLength); // set pixels - walkPixels(subSheet, m_model.img().bpp, [&](std::size_t i, uint8_t p) { + for (size_t i = 0; i < subSheet.pixels.size(); ++i) { + auto const p = subSheet.pixels[i]; auto color = gfx::color(pal, m_model.palettePage(), p); auto const pt = idxToPt(static_cast(i), subSheet.columns); auto const fx = static_cast(pt.x); @@ -148,7 +149,7 @@ void TileSheetPixels::setBufferObjects(ox::Vec2 const&paneSize) noexcept { color = applySelectionColor(color); } setPixelBufferObject(paneSize, static_cast(i * VertexVboRows), fx, fy, color, vbo, ebo); - }); + } } } diff --git a/src/nostalgia/modules/gfx/src/tilesheet.cpp b/src/nostalgia/modules/gfx/src/tilesheet.cpp index 1baa5e14..a3aa903c 100644 --- a/src/nostalgia/modules/gfx/src/tilesheet.cpp +++ b/src/nostalgia/modules/gfx/src/tilesheet.cpp @@ -70,30 +70,12 @@ ox::Optional getTileIdx(TileSheet const&ts, SubSheetId const id) noexcep return out ? ox::Optional{ox::in_place, *out / PixelsPerTile} : out; } -uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, std::size_t const idx) noexcept { - return ss.pixels[idx]; -} - -uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, std::size_t const idx) noexcept { - return ss.pixels[idx]; -} - uint8_t getPixel(TileSheet::SubSheet const&ss, std::size_t const idx) noexcept { return ss.pixels[idx]; } -uint8_t getPixel4Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept { - const auto idx = ptToIdx(pt, ss.columns); - return getPixel4Bpp(ss, idx); -} - -uint8_t getPixel8Bpp(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept { - const auto idx = ptToIdx(pt, ss.columns); - return getPixel8Bpp(ss, idx); -} - uint8_t getPixel(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept { - const auto idx = ptToIdx(pt, ss.columns); + auto const idx = ptToIdx(pt, ss.columns); return getPixel(ss, idx); } @@ -239,24 +221,13 @@ ox::Error rmSubSheet(TileSheet &ts, TileSheet::SubSheetIdx const&idx) noexcept { return rmSubSheet(ts, idx, 0, ts.subsheet); } -uint8_t getPixel4Bpp( +uint8_t getPixel( TileSheet const&ts, ox::Point const&pt, TileSheet::SubSheetIdx const&subsheetIdx) noexcept { - oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); auto &s = getSubSheet(ts, subsheetIdx); auto const idx = ptToIdx(pt, s.columns); - return getPixel4Bpp(s, idx); -} - -uint8_t getPixel8Bpp( - TileSheet const&ts, - ox::Point const&pt, - TileSheet::SubSheetIdx const&subsheetIdx) noexcept { - oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); - auto &s = getSubSheet(ts, subsheetIdx); - auto const idx = ptToIdx(pt, s.columns); - return getPixel8Bpp(s, idx); + return getPixel(s, idx); } uint8_t getPixel4Bpp( @@ -280,12 +251,18 @@ uint8_t getPixel8Bpp( ox::Pair get2Pixels4Bpp( CompactTileSheet const&ts, size_t const idx) noexcept { - return get2Pixels8Bpp(ts, idx); + oxAssert(ts.bpp == 4, "TileSheet::getPixel4Bpp: wrong bpp"); + auto const out = ts.pixels[idx / 2]; + return { + static_cast(out & 0x0f), + static_cast(out >> 4), + }; } ox::Pair get2Pixels8Bpp( CompactTileSheet const&ts, size_t const idx) noexcept { + oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp"); return { static_cast(ts.pixels[idx]), static_cast(ts.pixels[idx + 1]),