Compare commits

...

5 Commits

14 changed files with 182 additions and 106 deletions

View File

@ -144,7 +144,11 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
if (jv.empty()) {
*val = 0;
} else if (rightType) {
*val = static_cast<T>(jv.asUInt());
if constexpr(ox::is_signed_v<T>) {
*val = static_cast<T>(jv.asInt64());
} else {
*val = static_cast<T>(jv.asUInt64());
}
} else {
err = ox::Error(1, "Type mismatch");
}
@ -172,7 +176,8 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
err = ox::Error(1, "Type mismatch");
}
}
} catch (Json::LogicError const&) {
} catch (Json::LogicError const&e) {
oxDebugf("JSON error: {}", e.what());
err = ox::Error(1, "error reading JSON data");
}
++m_fieldIt;

View File

@ -171,7 +171,7 @@ class BasicString {
constexpr bool operator>=(BasicString const&other) const noexcept;
constexpr char operator[](std::size_t i) const noexcept;
constexpr char const&operator[](std::size_t i) const noexcept;
constexpr char &operator[](std::size_t i) noexcept;
@ -490,7 +490,7 @@ constexpr bool BasicString<SmallStringSize_v>::operator>=(BasicString const&othe
}
template<std::size_t SmallStringSize_v>
constexpr char BasicString<SmallStringSize_v>::operator[](std::size_t i) const noexcept {
constexpr char const&BasicString<SmallStringSize_v>::operator[](std::size_t i) const noexcept {
return m_buff[i];
}

12
release-notes.md Normal file
View File

@ -0,0 +1,12 @@
# d2025.02
* Rename core namespace to gfx.
* Add PaletteV5 to accommodate namespace change.
* Add TileSheetV5. TileSheetV5 retains the bpp field for the sake of
CompactTileSheet, but always store it pixel as 8 bpp for itself.
* Replace file picker combo boxes with support for dragging files from the
project explorer.
* Add ability to create directories.
* Add ability to delete files from the project explorer.
* Ctrl-<num key> keyboard shortcuts for jumping between tabs.
* Fix Palette Editor to ignore keyboard input when popups are open.

View File

@ -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<PaletteColorV2> colors;
constexpr PalettePageV2() noexcept = default;
constexpr PalettePageV2(ox::StringParam pName, ox::Vector<PaletteColorV2> pColors) noexcept:
name(std::move(pName)), colors(std::move(pColors)) {}
constexpr PalettePageV2(ox::StringParam pName, ox::Vector<Color16> 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<ox::String> colorNames;
ox::Vector<PalettePageV2> 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<ox::Vector<Color16>> 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();
}

View File

@ -339,9 +339,13 @@ struct TileSheetV5 {
static constexpr auto TypeName = "net.drinkingtea.nostalgia.gfx.TileSheet";
static constexpr auto TypeVersion = 5;
/**
* bpp is unused for TileSheet, but it does get used in CompactTileSheet.
* All pixel in TileSheet are 8 bpp, regardless of what the bpp field says.
*/
int8_t bpp = 4;
SubSheetId idIt = 0;
ox::FileAddress defaultPalette;
ox::String defaultPalette;
SubSheet subsheet{0, "Root", 1, 1};
};
@ -400,30 +404,12 @@ TileSheet::SubSheet const*getSubsheet(TileSheet const&ts, SubSheetId id) noexcep
[[nodiscard]]
ox::Optional<size_t> 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 +424,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 +432,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 +468,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 +488,7 @@ ox::Vector<uint8_t> 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;

View File

@ -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<PaletteV2>,
keel::generateTypeDesc<PaletteV3>,
keel::generateTypeDesc<PaletteV4>,
keel::generateTypeDesc<PaletteV5>,
keel::generateTypeDesc<CompactPaletteV1>,
};
}
@ -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<TileSheetV1> ||
typeId == ox::ModelTypeId_v<TileSheetV2> ||
typeId == ox::ModelTypeId_v<TileSheetV3> ||
typeId == ox::ModelTypeId_v<TileSheetV4>) {
typeId == ox::ModelTypeId_v<TileSheetV4> ||
typeId == ox::ModelTypeId_v<TileSheetV5>) {
OX_RETURN_ERROR(keel::convertBuffToBuff<CompactTileSheet>(
ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
return true;
@ -85,7 +89,8 @@ static class: public keel::Module {
typeId == ox::ModelTypeId_v<PaletteV1> ||
typeId == ox::ModelTypeId_v<PaletteV2> ||
typeId == ox::ModelTypeId_v<PaletteV3> ||
typeId == ox::ModelTypeId_v<PaletteV4>) {
typeId == ox::ModelTypeId_v<PaletteV4> ||
typeId == ox::ModelTypeId_v<PaletteV5>) {
OX_RETURN_ERROR(keel::convertBuffToBuff<CompactPalette>(
ctx, buff, ox::ClawFormat::Metal).moveTo(buff));
return true;

View File

@ -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<PaletteColorV2> 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]);
}
}
@ -167,8 +185,8 @@ ox::Error TileSheetV4ToTileSheetV5Converter::convert(
TileSheetV5 &dst) const noexcept {
dst.bpp = src.bpp;
dst.idIt = src.idIt;
dst.defaultPalette = std::move(src.defaultPalette);
convertSubsheet(dst.bpp, src.subsheet, dst.subsheet, dst.idIt);
OX_RETURN_ERROR(src.defaultPalette.getPath().moveTo(dst.defaultPalette));
convertSubsheet(dst.bpp, src.subsheet, dst.subsheet);
return {};
}
@ -178,7 +196,7 @@ ox::Error TileSheetToCompactTileSheetConverter::convert(
TileSheet &src,
CompactTileSheet &dst) const noexcept {
dst.bpp = src.bpp;
dst.defaultPalette = std::move(src.defaultPalette);
dst.defaultPalette = ox::FileAddress{src.defaultPalette};
dst.pixels = pixels(src);
return {};
}

View File

@ -21,15 +21,19 @@ class NostalgiaPaletteToPaletteV1Converter: public keel::Converter<NostalgiaPale
};
class PaletteV1ToPaletteV2Converter: public keel::Converter<PaletteV1, PaletteV2> {
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<PaletteV2, PaletteV3> {
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<PaletteV3, PaletteV4> {
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<PaletteV4, PaletteV5> {
ox::Error convert(keel::Context&, PaletteV4 &src, PaletteV5 &dst) const noexcept final;
};
class PaletteToCompactPaletteConverter: public keel::Converter<Palette, CompactPalette> {
@ -60,8 +64,7 @@ class TileSheetV4ToTileSheetV5Converter final: public keel::Converter<TileSheetV
static void convertSubsheet(
int bpp,
TileSheetV4::SubSheet &src,
TileSheetV5::SubSheet &dst,
SubSheetId &idIt) noexcept;
TileSheetV5::SubSheet &dst) noexcept;
ox::Error convert(keel::Context&, TileSheetV4 &src, TileSheetV5 &dst) const noexcept override;
};

View File

@ -258,7 +258,7 @@ void PaletteEditorImGui::drawColorEditor() noexcept {
std::ignore = pushCommand<ApplyColorAllPagesCommand>(
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 {

View File

@ -13,7 +13,7 @@ gfx::PaletteChangeCommand::PaletteChangeCommand(
m_img(img),
m_idx(std::move(idx)),
m_oldPalette(m_img.defaultPalette),
m_newPalette(ox::FileAddress(ox::sfmt<ox::IString<43>>("uuid://{}", newPalette))) {
m_newPalette(ox::sfmt<ox::IString<43>>("uuid://{}", newPalette)) {
}
ox::Error PaletteChangeCommand::redo() noexcept {

View File

@ -12,8 +12,8 @@ class PaletteChangeCommand: public TileSheetCommand {
private:
TileSheet &m_img;
TileSheet::SubSheetIdx m_idx;
ox::FileAddress m_oldPalette;
ox::FileAddress m_newPalette;
ox::String m_oldPalette;
ox::String m_newPalette;
public:
PaletteChangeCommand(

View File

@ -118,13 +118,10 @@ bool TileSheetEditorModel::acceptsClipboardPayload() const noexcept {
}
ox::StringView TileSheetEditorModel::palPath() const noexcept {
auto [path, err] = m_img.defaultPalette.getPath();
if (err) {
return {};
}
auto &path = m_img.defaultPalette;
constexpr ox::StringView uuidPrefix = "uuid://";
if (ox::beginsWith(path, uuidPrefix)) {
auto const uuid = ox::StringView(&path[uuidPrefix.bytes()], path.bytes() - uuidPrefix.bytes());
auto const uuid = substr(path, uuidPrefix.bytes());
auto const out = keelCtx(m_tctx).uuidToPath.at(uuid);
if (out.error) {
return {};
@ -282,7 +279,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 {

View File

@ -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<int>(i), subSheet.columns);
auto const fx = static_cast<float>(pt.x);
@ -148,7 +149,7 @@ void TileSheetPixels::setBufferObjects(ox::Vec2 const&paneSize) noexcept {
color = applySelectionColor(color);
}
setPixelBufferObject(paneSize, static_cast<unsigned>(i * VertexVboRows), fx, fy, color, vbo, ebo);
});
}
}
}

View File

@ -70,30 +70,12 @@ ox::Optional<size_t> getTileIdx(TileSheet const&ts, SubSheetId const id) noexcep
return out ? ox::Optional<size_t>{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<uint8_t> 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<uint8_t>(out & 0x0f),
static_cast<uint8_t>(out >> 4),
};
}
ox::Pair<uint8_t> get2Pixels8Bpp(
CompactTileSheet const&ts,
size_t const idx) noexcept {
oxAssert(ts.bpp == 8, "TileSheet::getPixel8Bpp: wrong bpp");
return {
static_cast<uint8_t>(ts.pixels[idx]),
static_cast<uint8_t>(ts.pixels[idx + 1]),