Compare commits
No commits in common. "8e816a261fcc3fb8d4293d8e7d235e7651d53783" and "8764444758cea952dcd0e27d9c6bc889a9ba07f2" have entirely different histories.
8e816a261f
...
8764444758
@ -111,15 +111,15 @@ static constexpr auto bgVertexRow(uint_t x, uint_t y) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void setSpriteBufferObject(
|
static void setSpriteBufferObject(
|
||||||
uint_t const vi,
|
uint_t vi,
|
||||||
float const enabled,
|
float enabled,
|
||||||
float x,
|
float x,
|
||||||
float y,
|
float y,
|
||||||
uint_t const textureRow,
|
uint_t textureRow,
|
||||||
uint_t const flipX,
|
uint_t flipX,
|
||||||
uint_t const priority,
|
uint_t priority,
|
||||||
ox::Span<float> const vbo,
|
ox::Span<float> vbo,
|
||||||
ox::Span<GLuint> const ebo) noexcept {
|
ox::Span<GLuint> ebo) noexcept {
|
||||||
// don't worry, this memcpy gets optimized to something much more ideal
|
// don't worry, this memcpy gets optimized to something much more ideal
|
||||||
constexpr float xmod = 0.1f;
|
constexpr float xmod = 0.1f;
|
||||||
constexpr float ymod = 0.1f;
|
constexpr float ymod = 0.1f;
|
||||||
@ -147,16 +147,16 @@ static void setSpriteBufferObject(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void setTileBufferObject(
|
static void setTileBufferObject(
|
||||||
uint_t const vi,
|
uint_t vi,
|
||||||
float x,
|
float x,
|
||||||
float y,
|
float y,
|
||||||
float const textureTileIdx,
|
float textureTileIdx,
|
||||||
float const priority,
|
float priority,
|
||||||
float const palOffset,
|
float palOffset,
|
||||||
bool const flipX,
|
bool flipX,
|
||||||
bool const flipY,
|
bool flipY,
|
||||||
ox::Span<float> const vbo,
|
ox::Span<float> vbo,
|
||||||
ox::Span<GLuint> const ebo) noexcept {
|
ox::Span<GLuint> ebo) noexcept {
|
||||||
// don't worry, this memcpy gets optimized to something much more ideal
|
// don't worry, this memcpy gets optimized to something much more ideal
|
||||||
constexpr float ymod = 0.1f;
|
constexpr float ymod = 0.1f;
|
||||||
constexpr float xmod = 0.1f;
|
constexpr float xmod = 0.1f;
|
||||||
|
@ -9,24 +9,27 @@ namespace nostalgia::core {
|
|||||||
core::UpdateSubSheetCommand::UpdateSubSheetCommand(
|
core::UpdateSubSheetCommand::UpdateSubSheetCommand(
|
||||||
TileSheet &img,
|
TileSheet &img,
|
||||||
TileSheet::SubSheetIdx idx,
|
TileSheet::SubSheetIdx idx,
|
||||||
ox::StringParam name,
|
ox::String name,
|
||||||
int const cols,
|
int cols,
|
||||||
int const rows):
|
int rows) noexcept:
|
||||||
m_img{img},
|
m_img(img),
|
||||||
m_idx{std::move(idx)},
|
m_idx(std::move(idx)),
|
||||||
m_sheet{getSubSheet(m_img, m_idx)} {
|
m_sheet(getSubSheet(m_img, m_idx)),
|
||||||
m_sheet = getSubSheet(m_img, m_idx);
|
m_newName(std::move(name)),
|
||||||
m_sheet.name = std::move(name);
|
m_newCols(cols),
|
||||||
OX_THROW_ERROR(resizeSubsheet(m_sheet, m_img.bpp, {cols, rows}));
|
m_newRows(rows) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error UpdateSubSheetCommand::redo() noexcept {
|
ox::Error UpdateSubSheetCommand::redo() noexcept {
|
||||||
std::swap(m_sheet, getSubSheet(m_img, m_idx));
|
auto &sheet = getSubSheet(m_img, m_idx);
|
||||||
|
sheet.name = m_newName;
|
||||||
|
oxLogError(resizeSubsheet(sheet, m_img.bpp, {m_newCols, m_newRows}));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error UpdateSubSheetCommand::undo() noexcept {
|
ox::Error UpdateSubSheetCommand::undo() noexcept {
|
||||||
std::swap(m_sheet, getSubSheet(m_img, m_idx));
|
auto &sheet = getSubSheet(m_img, m_idx);
|
||||||
|
sheet = m_sheet;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,14 +13,17 @@ class UpdateSubSheetCommand: public TileSheetCommand {
|
|||||||
TileSheet &m_img;
|
TileSheet &m_img;
|
||||||
TileSheet::SubSheetIdx m_idx;
|
TileSheet::SubSheetIdx m_idx;
|
||||||
TileSheet::SubSheet m_sheet;
|
TileSheet::SubSheet m_sheet;
|
||||||
|
ox::String m_newName;
|
||||||
|
int m_newCols = 0;
|
||||||
|
int m_newRows = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UpdateSubSheetCommand(
|
UpdateSubSheetCommand(
|
||||||
TileSheet &img,
|
TileSheet &img,
|
||||||
TileSheet::SubSheetIdx idx,
|
TileSheet::SubSheetIdx idx,
|
||||||
ox::StringParam name,
|
ox::String name,
|
||||||
int cols,
|
int cols,
|
||||||
int rows);
|
int rows) noexcept;
|
||||||
|
|
||||||
ox::Error redo() noexcept final;
|
ox::Error redo() noexcept final;
|
||||||
|
|
||||||
|
@ -26,6 +26,11 @@
|
|||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
|
Palette const TileSheetEditorModel::s_defaultPalette = {
|
||||||
|
.colorNames = {ox::Vector<ox::String>{{}}},
|
||||||
|
.pages = {{"Page 1", ox::Vector<Color16>(128)}},
|
||||||
|
};
|
||||||
|
|
||||||
// delete pixels of all non-leaf nodes
|
// delete pixels of all non-leaf nodes
|
||||||
static void normalizeSubsheets(TileSheet::SubSheet &ss) noexcept {
|
static void normalizeSubsheets(TileSheet::SubSheet &ss) noexcept {
|
||||||
if (ss.subsheets.empty()) {
|
if (ss.subsheets.empty()) {
|
||||||
@ -37,14 +42,7 @@ static void normalizeSubsheets(TileSheet::SubSheet &ss) noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TileSheetEditorModel::TileSheetEditorModel(studio::StudioContext &sctx, ox::StringView path, studio::UndoStack &undoStack):
|
||||||
Palette const TileSheetEditorModel::s_defaultPalette = {
|
|
||||||
.colorNames = {ox::Vector<ox::String>{{}}},
|
|
||||||
.pages = {{"Page 1", ox::Vector<Color16>(128)}},
|
|
||||||
};
|
|
||||||
|
|
||||||
TileSheetEditorModel::TileSheetEditorModel(
|
|
||||||
studio::StudioContext &sctx, ox::StringViewCR path, studio::UndoStack &undoStack):
|
|
||||||
m_sctx(sctx),
|
m_sctx(sctx),
|
||||||
m_tctx(m_sctx.tctx),
|
m_tctx(m_sctx.tctx),
|
||||||
m_path(path),
|
m_path(path),
|
||||||
@ -64,7 +62,7 @@ void TileSheetEditorModel::cut() {
|
|||||||
TileSheetClipboard blankCb;
|
TileSheetClipboard blankCb;
|
||||||
auto cb = ox::make_unique<TileSheetClipboard>();
|
auto cb = ox::make_unique<TileSheetClipboard>();
|
||||||
auto const&s = activeSubSheet();
|
auto const&s = activeSubSheet();
|
||||||
iterateSelectionRows(*m_selection, [&](int const x, int const y) {
|
iterateSelectionRows(*m_selection, [&](int x, int y) {
|
||||||
auto pt = ox::Point{x, y};
|
auto pt = ox::Point{x, y};
|
||||||
auto const idx = core::idx(s, pt);
|
auto const idx = core::idx(s, pt);
|
||||||
auto const c = getPixel(s, m_img.bpp, idx);
|
auto const c = getPixel(s, m_img.bpp, idx);
|
||||||
@ -75,8 +73,7 @@ void TileSheetEditorModel::cut() {
|
|||||||
auto const pt1 = m_selection->a;
|
auto const pt1 = m_selection->a;
|
||||||
auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight};
|
auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight};
|
||||||
turbine::setClipboardObject(m_tctx, std::move(cb));
|
turbine::setClipboardObject(m_tctx, std::move(cb));
|
||||||
pushCommand(ox::make<CutPasteCommand>(
|
pushCommand(ox::make<CutPasteCommand>(CommandId::Cut, m_img, m_activeSubsSheetIdx, pt1, pt2, blankCb));
|
||||||
CommandId::Cut, m_img, m_activeSubsSheetIdx, pt1, pt2, blankCb));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::copy() {
|
void TileSheetEditorModel::copy() {
|
||||||
@ -84,7 +81,7 @@ void TileSheetEditorModel::copy() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto cb = ox::make_unique<TileSheetClipboard>();
|
auto cb = ox::make_unique<TileSheetClipboard>();
|
||||||
iterateSelectionRows(*m_selection, [&](int const x, int const y) {
|
iterateSelectionRows(*m_selection, [&](int x, int y) {
|
||||||
auto pt = ox::Point{x, y};
|
auto pt = ox::Point{x, y};
|
||||||
const auto&s = activeSubSheet();
|
const auto&s = activeSubSheet();
|
||||||
const auto idx = core::idx(s, pt);
|
const auto idx = core::idx(s, pt);
|
||||||
@ -108,8 +105,7 @@ void TileSheetEditorModel::paste() {
|
|||||||
auto const&s = activeSubSheet();
|
auto const&s = activeSubSheet();
|
||||||
auto const pt1 = m_selection->a;
|
auto const pt1 = m_selection->a;
|
||||||
auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight};
|
auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight};
|
||||||
pushCommand(ox::make<CutPasteCommand>(
|
pushCommand(ox::make<CutPasteCommand>(CommandId::Paste, m_img, m_activeSubsSheetIdx, pt1, pt2, *cb));
|
||||||
CommandId::Paste, m_img, m_activeSubsSheetIdx, pt1, pt2, *cb));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TileSheetEditorModel::acceptsClipboardPayload() const noexcept {
|
bool TileSheetEditorModel::acceptsClipboardPayload() const noexcept {
|
||||||
@ -124,8 +120,8 @@ ox::StringView TileSheetEditorModel::palPath() const noexcept {
|
|||||||
}
|
}
|
||||||
constexpr ox::StringView uuidPrefix = "uuid://";
|
constexpr ox::StringView uuidPrefix = "uuid://";
|
||||||
if (ox::beginsWith(path, uuidPrefix)) {
|
if (ox::beginsWith(path, uuidPrefix)) {
|
||||||
auto const uuid = ox::StringView(&path[uuidPrefix.bytes()], path.bytes() - uuidPrefix.bytes());
|
auto uuid = ox::StringView(&path[uuidPrefix.bytes()], path.bytes() - uuidPrefix.bytes());
|
||||||
auto const out = keelCtx(m_tctx).uuidToPath.at(uuid);
|
auto out = keelCtx(m_tctx).uuidToPath.at(uuid);
|
||||||
if (out.error) {
|
if (out.error) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -135,14 +131,13 @@ ox::StringView TileSheetEditorModel::palPath() const noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::setPalette(ox::StringViewCR path) noexcept {
|
ox::Error TileSheetEditorModel::setPalette(ox::StringView path) noexcept {
|
||||||
OX_REQUIRE(uuid, keelCtx(m_tctx).pathToUuid.at(path));
|
OX_REQUIRE(uuid, keelCtx(m_tctx).pathToUuid.at(path));
|
||||||
pushCommand(ox::make<PaletteChangeCommand>(
|
pushCommand(ox::make<PaletteChangeCommand>(activeSubSheetIdx(), m_img, uuid->toString()));
|
||||||
activeSubSheetIdx(), m_img, uuid->toString()));
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::setPalettePage(size_t const pg) noexcept {
|
void TileSheetEditorModel::setPalettePage(size_t pg) noexcept {
|
||||||
m_palettePage = ox::clamp<size_t>(pg, 0, m_pal->pages.size() - 1);
|
m_palettePage = ox::clamp<size_t>(pg, 0, m_pal->pages.size() - 1);
|
||||||
m_updated = true;
|
m_updated = true;
|
||||||
}
|
}
|
||||||
@ -151,7 +146,7 @@ size_t TileSheetEditorModel::palettePage() const noexcept {
|
|||||||
return m_palettePage;
|
return m_palettePage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::drawCommand(ox::Point const&pt, std::size_t const palIdx) noexcept {
|
void TileSheetEditorModel::drawCommand(ox::Point const&pt, std::size_t palIdx) noexcept {
|
||||||
const auto &activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx);
|
const auto &activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx);
|
||||||
if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) {
|
if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) {
|
||||||
return;
|
return;
|
||||||
@ -160,8 +155,7 @@ void TileSheetEditorModel::drawCommand(ox::Point const&pt, std::size_t const pal
|
|||||||
if (m_ongoingDrawCommand) {
|
if (m_ongoingDrawCommand) {
|
||||||
m_updated = m_updated || m_ongoingDrawCommand->append(idx);
|
m_updated = m_updated || m_ongoingDrawCommand->append(idx);
|
||||||
} else if (getPixel(activeSubSheet, m_img.bpp, idx) != palIdx) {
|
} else if (getPixel(activeSubSheet, m_img.bpp, idx) != palIdx) {
|
||||||
pushCommand(ox::make<DrawCommand>(
|
pushCommand(ox::make<DrawCommand>(m_img, m_activeSubsSheetIdx, idx, static_cast<int>(palIdx)));
|
||||||
m_img, m_activeSubsSheetIdx, idx, static_cast<int>(palIdx)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,20 +171,16 @@ void TileSheetEditorModel::rmSubsheet(TileSheet::SubSheetIdx const&idx) noexcept
|
|||||||
pushCommand(ox::make<RmSubSheetCommand>(m_img, idx));
|
pushCommand(ox::make<RmSubSheetCommand>(m_img, idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::insertTiles(
|
void TileSheetEditorModel::insertTiles(TileSheet::SubSheetIdx const&idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
||||||
TileSheet::SubSheetIdx const&idx, std::size_t const tileIdx, std::size_t const tileCnt) noexcept {
|
|
||||||
pushCommand(ox::make<InsertTilesCommand>(m_img, idx, tileIdx, tileCnt));
|
pushCommand(ox::make<InsertTilesCommand>(m_img, idx, tileIdx, tileCnt));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::deleteTiles(
|
void TileSheetEditorModel::deleteTiles(TileSheet::SubSheetIdx const&idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
||||||
TileSheet::SubSheetIdx const&idx, std::size_t const tileIdx, std::size_t const tileCnt) noexcept {
|
|
||||||
pushCommand(ox::make<DeleteTilesCommand>(m_img, idx, tileIdx, tileCnt));
|
pushCommand(ox::make<DeleteTilesCommand>(m_img, idx, tileIdx, tileCnt));
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::updateSubsheet(
|
ox::Error TileSheetEditorModel::updateSubsheet(TileSheet::SubSheetIdx const&idx, ox::StringView const&name, int cols, int rows) noexcept {
|
||||||
TileSheet::SubSheetIdx const&idx, ox::StringViewCR name, int const cols, int const rows) noexcept {
|
pushCommand(ox::make<UpdateSubSheetCommand>(m_img, idx, ox::String(name), cols, rows));
|
||||||
OX_REQUIRE(cmd, ox::makeCatch<UpdateSubSheetCommand>(m_img, idx, name, cols, rows));
|
|
||||||
pushCommand(cmd);
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +189,7 @@ void TileSheetEditorModel::setActiveSubsheet(TileSheet::SubSheetIdx const&idx) n
|
|||||||
this->activeSubsheetChanged.emit(m_activeSubsSheetIdx);
|
this->activeSubsheetChanged.emit(m_activeSubsSheetIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::fill(ox::Point const&pt, int const palIdx) noexcept {
|
void TileSheetEditorModel::fill(ox::Point const&pt, int palIdx) noexcept {
|
||||||
auto const&activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx);
|
auto const&activeSubSheet = getSubSheet(m_img, m_activeSubsSheetIdx);
|
||||||
// build idx list
|
// build idx list
|
||||||
if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) {
|
if (pt.x >= activeSubSheet.columns * TileWidth || pt.y >= activeSubSheet.rows * TileHeight) {
|
||||||
@ -207,10 +197,10 @@ void TileSheetEditorModel::fill(ox::Point const&pt, int const palIdx) noexcept {
|
|||||||
}
|
}
|
||||||
ox::Array<bool, PixelsPerTile> updateMap = {};
|
ox::Array<bool, PixelsPerTile> updateMap = {};
|
||||||
auto const oldColor = getPixel(activeSubSheet, m_img.bpp, pt);
|
auto const oldColor = getPixel(activeSubSheet, m_img.bpp, pt);
|
||||||
getFillPixels(activeSubSheet, updateMap, pt, oldColor);
|
getFillPixels(updateMap, pt, oldColor);
|
||||||
ox::Vector<std::size_t> idxList;
|
ox::Vector<std::size_t> idxList;
|
||||||
auto i = core::idx(activeSubSheet, pt) / PixelsPerTile * PixelsPerTile;
|
auto i = core::idx(activeSubSheet, pt) / PixelsPerTile * PixelsPerTile;
|
||||||
for (auto const u : updateMap) {
|
for (auto u : updateMap) {
|
||||||
if (u) {
|
if (u) {
|
||||||
idxList.emplace_back(i);
|
idxList.emplace_back(i);
|
||||||
}
|
}
|
||||||
@ -240,7 +230,7 @@ void TileSheetEditorModel::completeSelection() noexcept {
|
|||||||
m_selTracker.finishSelection();
|
m_selTracker.finishSelection();
|
||||||
m_selection.emplace(m_selTracker.selection());
|
m_selection.emplace(m_selTracker.selection());
|
||||||
auto&pt = m_selection->b;
|
auto&pt = m_selection->b;
|
||||||
auto const&s = activeSubSheet();
|
auto&s = activeSubSheet();
|
||||||
pt.x = ox::min(s.columns * TileWidth - 1, pt.x);
|
pt.x = ox::min(s.columns * TileWidth - 1, pt.x);
|
||||||
pt.y = ox::min(s.rows * TileHeight - 1, pt.y);
|
pt.y = ox::min(s.rows * TileHeight - 1, pt.y);
|
||||||
}
|
}
|
||||||
@ -285,44 +275,47 @@ 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::Metal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TileSheetEditorModel::pixelSelected(std::size_t const idx) const noexcept {
|
bool TileSheetEditorModel::pixelSelected(std::size_t idx) const noexcept {
|
||||||
auto const&s = activeSubSheet();
|
auto const&s = activeSubSheet();
|
||||||
auto const pt = idxToPt(static_cast<int>(idx), s.columns);
|
auto const pt = idxToPt(static_cast<int>(idx), s.columns);
|
||||||
return m_selection && m_selection->contains(pt);
|
return m_selection && m_selection->contains(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::getFillPixels(
|
void TileSheetEditorModel::getFillPixels(ox::Span<bool> pixels, ox::Point const&pt, int oldColor) const noexcept {
|
||||||
TileSheet::SubSheet const&activeSubSheet,
|
const auto &activeSubSheet = this->activeSubSheet();
|
||||||
ox::Span<bool> pixels,
|
const auto tileIdx = [activeSubSheet](const ox::Point &pt) noexcept {
|
||||||
ox::Point const&pt,
|
return ptToIdx(pt, activeSubSheet.columns) / PixelsPerTile;
|
||||||
int const oldColor) const noexcept {
|
};
|
||||||
auto const idx = ptToIdx(pt, activeSubSheet.columns);
|
// get points
|
||||||
auto const relIdx = idx % PixelsPerTile;
|
const auto leftPt = pt + ox::Point(-1, 0);
|
||||||
if (pixels[relIdx] || getPixel(activeSubSheet, m_img.bpp, idx) != oldColor) {
|
const auto rightPt = pt + ox::Point(1, 0);
|
||||||
return;
|
const auto topPt = pt + ox::Point(0, -1);
|
||||||
}
|
const auto bottomPt = pt + ox::Point(0, 1);
|
||||||
|
// calculate indices
|
||||||
|
const auto idx = ptToIdx(pt, activeSubSheet.columns);
|
||||||
|
const auto leftIdx = ptToIdx(leftPt, activeSubSheet.columns);
|
||||||
|
const auto rightIdx = ptToIdx(rightPt, activeSubSheet.columns);
|
||||||
|
const auto topIdx = ptToIdx(topPt, activeSubSheet.columns);
|
||||||
|
const auto bottomIdx = ptToIdx(bottomPt, activeSubSheet.columns);
|
||||||
|
const auto tile = tileIdx(pt);
|
||||||
// mark pixels to update
|
// mark pixels to update
|
||||||
pixels[relIdx] = true;
|
pixels[idx % PixelsPerTile] = true;
|
||||||
if (pt.x % TileWidth != 0) {
|
if (!pixels[leftIdx % PixelsPerTile] && tile == tileIdx(leftPt) && getPixel(activeSubSheet, m_img.bpp, leftIdx) == oldColor) {
|
||||||
auto const leftPt = pt + ox::Point{-1, 0};
|
getFillPixels(pixels, leftPt, oldColor);
|
||||||
getFillPixels(activeSubSheet, pixels, leftPt, oldColor);
|
|
||||||
}
|
}
|
||||||
if (pt.x % TileWidth != TileWidth - 1) {
|
if (!pixels[rightIdx % PixelsPerTile] && tile == tileIdx(rightPt) && getPixel(activeSubSheet, m_img.bpp, rightIdx) == oldColor) {
|
||||||
auto const rightPt = pt + ox::Point{1, 0};
|
getFillPixels(pixels, rightPt, oldColor);
|
||||||
getFillPixels(activeSubSheet, pixels, rightPt, oldColor);
|
|
||||||
}
|
}
|
||||||
if (pt.y % TileHeight != 0) {
|
if (!pixels[topIdx % PixelsPerTile] && tile == tileIdx(topPt) && getPixel(activeSubSheet, m_img.bpp, topIdx) == oldColor) {
|
||||||
auto const topPt = pt + ox::Point{0, -1};
|
getFillPixels(pixels, topPt, oldColor);
|
||||||
getFillPixels(activeSubSheet, pixels, topPt, oldColor);
|
|
||||||
}
|
}
|
||||||
if (pt.y % TileHeight != TileHeight - 1) {
|
if (!pixels[bottomIdx % PixelsPerTile] && tile == tileIdx(bottomPt) && getPixel(activeSubSheet, m_img.bpp, bottomIdx) == oldColor) {
|
||||||
auto const bottomPt = pt + ox::Point{0, 1};
|
getFillPixels(pixels, bottomPt, oldColor);
|
||||||
getFillPixels(activeSubSheet, pixels, bottomPt, oldColor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::pushCommand(studio::UndoCommand *cmd) noexcept {
|
void TileSheetEditorModel::pushCommand(studio::UndoCommand *cmd) noexcept {
|
||||||
std::ignore = m_undoStack.push(ox::UPtr<studio::UndoCommand>{cmd});
|
std::ignore = m_undoStack.push(ox::UPtr<studio::UndoCommand>(cmd));
|
||||||
m_ongoingDrawCommand = dynamic_cast<DrawCommand*>(cmd);
|
m_ongoingDrawCommand = dynamic_cast<DrawCommand*>(cmd);
|
||||||
m_updated = true;
|
m_updated = true;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ox/std/bounds.hpp>
|
||||||
#include <ox/std/point.hpp>
|
#include <ox/std/point.hpp>
|
||||||
|
#include <ox/std/trace.hpp>
|
||||||
#include <ox/std/string.hpp>
|
#include <ox/std/string.hpp>
|
||||||
|
|
||||||
#include <studio/studio.hpp>
|
#include <studio/studio.hpp>
|
||||||
@ -36,7 +38,7 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
|||||||
bool m_updated = false;
|
bool m_updated = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TileSheetEditorModel(studio::StudioContext &sctx, ox::StringViewCR path, studio::UndoStack &undoStack);
|
TileSheetEditorModel(studio::StudioContext &sctx, ox::StringView path, studio::UndoStack &undoStack);
|
||||||
|
|
||||||
~TileSheetEditorModel() override = default;
|
~TileSheetEditorModel() override = default;
|
||||||
|
|
||||||
@ -61,7 +63,7 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ox::StringView palPath() const noexcept;
|
ox::StringView palPath() const noexcept;
|
||||||
|
|
||||||
ox::Error setPalette(ox::StringViewCR path) noexcept;
|
ox::Error setPalette(ox::StringView path) noexcept;
|
||||||
|
|
||||||
void setPalettePage(size_t pg) noexcept;
|
void setPalettePage(size_t pg) noexcept;
|
||||||
|
|
||||||
@ -126,11 +128,7 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
|||||||
bool pixelSelected(std::size_t idx) const noexcept;
|
bool pixelSelected(std::size_t idx) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void getFillPixels(
|
void getFillPixels(ox::Span<bool> pixels, ox::Point const&pt, int oldColor) const noexcept;
|
||||||
TileSheet::SubSheet const&activeSubSheet,
|
|
||||||
ox::Span<bool> pixels,
|
|
||||||
ox::Point const&pt,
|
|
||||||
int oldColor) const noexcept;
|
|
||||||
|
|
||||||
void pushCommand(studio::UndoCommand *cmd) noexcept;
|
void pushCommand(studio::UndoCommand *cmd) noexcept;
|
||||||
|
|
||||||
|
@ -125,9 +125,7 @@ ox::Error preloadObj(
|
|||||||
OX_RETURN_ERROR(err);
|
OX_RETURN_ERROR(err);
|
||||||
keel::PreloadPtr const p{.preloadAddr = a};
|
keel::PreloadPtr const p{.preloadAddr = a};
|
||||||
OX_RETURN_ERROR(ox::writeMC(p).moveTo(buff));
|
OX_RETURN_ERROR(ox::writeMC(p).moveTo(buff));
|
||||||
auto const&pbufSz = pl.buff().size();
|
oxOutf("preloaded {} as a {} @ {} to {}\n", path, obj.type()->typeName, a, a + size);
|
||||||
oxOutf("preloaded {} as a {} @ {} to {} / {}, total size: {}\n",
|
|
||||||
path, obj.type()->typeName, a, a + size, pbufSz - 1, pbufSz - a);
|
|
||||||
} else {
|
} else {
|
||||||
// strip the Claw header (it is not needed after preloading) and write back out to dest fs
|
// strip the Claw header (it is not needed after preloading) and write back out to dest fs
|
||||||
OX_RETURN_ERROR(ox::writeMC(obj).moveTo(buff));
|
OX_RETURN_ERROR(ox::writeMC(obj).moveTo(buff));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user