[nostalgia,studio] Update for Ox changes, cleanup
This commit is contained in:
parent
dde51151ff
commit
ba50b083ff
@ -17,12 +17,6 @@
|
|||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
namespace gl {
|
|
||||||
|
|
||||||
void drawMainView(core::Context *ctx, ox::Size const&renderSz) noexcept;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace renderer {
|
namespace renderer {
|
||||||
|
|
||||||
void Drawer::draw(turbine::Context &tctx) noexcept {
|
void Drawer::draw(turbine::Context &tctx) noexcept {
|
||||||
@ -79,14 +73,16 @@ static constexpr auto bgVertexRow(unsigned x, unsigned y) noexcept {
|
|||||||
return y * TileRows + x;
|
return y * TileRows + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setSpriteBufferObject(Context*,
|
static void setSpriteBufferObject(
|
||||||
unsigned vi,
|
Context*,
|
||||||
float enabled,
|
unsigned vi,
|
||||||
float x, float y,
|
float enabled,
|
||||||
unsigned textureRow,
|
float x,
|
||||||
unsigned flipX,
|
float y,
|
||||||
float *vbo,
|
unsigned textureRow,
|
||||||
GLuint *ebo) noexcept {
|
unsigned flipX,
|
||||||
|
float *vbo,
|
||||||
|
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;
|
||||||
@ -111,13 +107,14 @@ static void setSpriteBufferObject(Context*,
|
|||||||
memcpy(ebo, elms.data(), sizeof(elms));
|
memcpy(ebo, elms.data(), sizeof(elms));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setTileBufferObject(Context*,
|
static void setTileBufferObject(
|
||||||
unsigned vi,
|
Context*,
|
||||||
float x,
|
unsigned vi,
|
||||||
float y,
|
float x,
|
||||||
unsigned textureRow,
|
float y,
|
||||||
float *vbo,
|
unsigned textureRow,
|
||||||
GLuint *ebo) noexcept {
|
float *vbo,
|
||||||
|
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;
|
||||||
@ -166,7 +163,8 @@ static void initBackgroundBufferObjects(Context *ctx, glutils::BufferSet *bg) no
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initSpritesBufferset(Context *ctx, GLuint shader, glutils::BufferSet *bs) noexcept {
|
static void initSpritesBufferset(
|
||||||
|
Context *ctx, GLuint shader, glutils::BufferSet *bs) noexcept {
|
||||||
// vao
|
// vao
|
||||||
bs->vao = glutils::generateVertexArrayObject();
|
bs->vao = glutils::generateVertexArrayObject();
|
||||||
glBindVertexArray(bs->vao);
|
glBindVertexArray(bs->vao);
|
||||||
@ -190,7 +188,10 @@ static void initSpritesBufferset(Context *ctx, GLuint shader, glutils::BufferSet
|
|||||||
reinterpret_cast<void*>(3 * sizeof(float)));
|
reinterpret_cast<void*>(3 * sizeof(float)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initBackgroundBufferset(Context *ctx, GLuint shader, glutils::BufferSet *bg) noexcept {
|
static void initBackgroundBufferset(
|
||||||
|
Context *ctx,
|
||||||
|
GLuint shader,
|
||||||
|
glutils::BufferSet *bg) noexcept {
|
||||||
// vao
|
// vao
|
||||||
bg->vao = glutils::generateVertexArrayObject();
|
bg->vao = glutils::generateVertexArrayObject();
|
||||||
glBindVertexArray(bg->vao);
|
glBindVertexArray(bg->vao);
|
||||||
@ -210,7 +211,10 @@ static void initBackgroundBufferset(Context *ctx, GLuint shader, glutils::Buffer
|
|||||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static glutils::GLTexture loadTexture(GLsizei w, GLsizei h, const void *pixels) noexcept {
|
static glutils::GLTexture loadTexture(
|
||||||
|
GLsizei w,
|
||||||
|
GLsizei h,
|
||||||
|
const void *pixels) noexcept {
|
||||||
GLuint texId = 0;
|
GLuint texId = 0;
|
||||||
glGenTextures(1, &texId);
|
glGenTextures(1, &texId);
|
||||||
glutils::GLTexture tex(texId);
|
glutils::GLTexture tex(texId);
|
||||||
@ -236,7 +240,9 @@ static void drawBackground(CBB *cbb) noexcept {
|
|||||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(cbb->elements.size()), GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(cbb->elements.size()), GL_UNSIGNED_INT, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawBackgrounds(GlContext *gctx, ox::Size const&renderSz) noexcept {
|
static void drawBackgrounds(
|
||||||
|
GlContext *gctx,
|
||||||
|
ox::Size const&renderSz) noexcept {
|
||||||
// load background shader and its uniforms
|
// load background shader and its uniforms
|
||||||
glUseProgram(gctx->bgShader);
|
glUseProgram(gctx->bgShader);
|
||||||
const auto uniformXScale = static_cast<GLint>(glGetUniformLocation(gctx->bgShader, "vXScale"));
|
const auto uniformXScale = static_cast<GLint>(glGetUniformLocation(gctx->bgShader, "vXScale"));
|
||||||
@ -278,7 +284,10 @@ static void drawSprites(GlContext *gctx, ox::Size const&renderSz) noexcept {
|
|||||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sb.elements.size()), GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sb.elements.size()), GL_UNSIGNED_INT, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadPalette(GLuint shaderPgrm, const Palette &pal, bool firstIsTransparent = false) noexcept {
|
static void loadPalette(
|
||||||
|
GLuint shaderPgrm,
|
||||||
|
const Palette &pal,
|
||||||
|
bool firstIsTransparent = false) noexcept {
|
||||||
static constexpr std::size_t ColorCnt = 256;
|
static constexpr std::size_t ColorCnt = 256;
|
||||||
ox::Array<GLfloat, ColorCnt * 4> palette{};
|
ox::Array<GLfloat, ColorCnt * 4> palette{};
|
||||||
for (auto i = 0u; const auto c : pal.colors) {
|
for (auto i = 0u; const auto c : pal.colors) {
|
||||||
@ -303,19 +312,30 @@ static void loadSpritePalette(GlContext *gctx, const Palette &pal) noexcept {
|
|||||||
loadPalette(gctx->spriteShader, pal, true);
|
loadPalette(gctx->spriteShader, pal, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadBgTexture(GlContext *gctx, unsigned cbbIdx, const void *pixels, int w, int h) noexcept {
|
static void loadBgTexture(
|
||||||
|
GlContext *gctx,
|
||||||
|
unsigned cbbIdx,
|
||||||
|
const void *pixels,
|
||||||
|
int w,
|
||||||
|
int h) noexcept {
|
||||||
oxTracef("nostalgia::core::gfx::gl", "loadBgTexture: { cbbIdx: {}, w: {}, h: {} }", cbbIdx, w, h);
|
oxTracef("nostalgia::core::gfx::gl", "loadBgTexture: { cbbIdx: {}, w: {}, h: {} }", cbbIdx, w, h);
|
||||||
gctx->cbbs[cbbIdx].tex = loadTexture(w, h, pixels);
|
gctx->cbbs[cbbIdx].tex = loadTexture(w, h, pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadSpriteTexture(GlContext *gctx, const void *pixels, int w, int h) noexcept {
|
static void loadSpriteTexture(
|
||||||
|
GlContext *gctx,
|
||||||
|
const void *pixels,
|
||||||
|
int w,
|
||||||
|
int h) noexcept {
|
||||||
oxTracef("nostalgia::core::gfx::gl", "loadSpriteTexture: { w: {}, h: {} }", w, h);
|
oxTracef("nostalgia::core::gfx::gl", "loadSpriteTexture: { w: {}, h: {} }", w, h);
|
||||||
gctx->spriteBlocks.tex = loadTexture(w, h, pixels);
|
gctx->spriteBlocks.tex = loadTexture(w, h, pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error initGfx(Context *ctx, const InitParams &initParams) noexcept {
|
ox::Error initGfx(
|
||||||
|
Context *ctx,
|
||||||
|
const InitParams &initParams) noexcept {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
const auto bgVshad = ox::sfmt(renderer::bgvshadTmpl, glutils::GlslVersion);
|
const auto bgVshad = ox::sfmt(renderer::bgvshadTmpl, glutils::GlslVersion);
|
||||||
@ -355,7 +375,8 @@ struct TileSheetData {
|
|||||||
int height = 0;
|
int height = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
ox::Result<TileSheetData> loadTileSheet(Context *ctx, const CompactTileSheet &tilesheet) noexcept {
|
ox::Result<TileSheetData> loadTileSheet(
|
||||||
|
Context *ctx, const CompactTileSheet &tilesheet) noexcept {
|
||||||
auto &gctx = static_cast<GlContext&>(*ctx);
|
auto &gctx = static_cast<GlContext&>(*ctx);
|
||||||
const unsigned bytesPerTile = tilesheet.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2;
|
const unsigned bytesPerTile = tilesheet.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2;
|
||||||
const auto tiles = tilesheet.pixels.size() / bytesPerTile;
|
const auto tiles = tilesheet.pixels.size() / bytesPerTile;
|
||||||
@ -378,10 +399,11 @@ ox::Result<TileSheetData> loadTileSheet(Context *ctx, const CompactTileSheet &ti
|
|||||||
return TileSheetData{std::move(pixels), width, height};
|
return TileSheetData{std::move(pixels), width, height};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error loadBgTileSheet(Context *ctx,
|
ox::Error loadBgTileSheet(
|
||||||
unsigned cbb,
|
Context *ctx,
|
||||||
const ox::FileAddress &tilesheetAddr,
|
unsigned cbb,
|
||||||
const ox::FileAddress &paletteAddr) noexcept {
|
const ox::FileAddress &tilesheetAddr,
|
||||||
|
const ox::FileAddress &paletteAddr) noexcept {
|
||||||
auto &gctx = static_cast<GlContext&>(*ctx);
|
auto &gctx = static_cast<GlContext&>(*ctx);
|
||||||
auto &kctx = *gctx.turbineCtx;
|
auto &kctx = *gctx.turbineCtx;
|
||||||
oxRequire(tilesheet, readObj<CompactTileSheet>(&kctx, tilesheetAddr));
|
oxRequire(tilesheet, readObj<CompactTileSheet>(&kctx, tilesheetAddr));
|
||||||
@ -392,9 +414,10 @@ ox::Error loadBgTileSheet(Context *ctx,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error loadSpriteTileSheet(Context *ctx,
|
ox::Error loadSpriteTileSheet(
|
||||||
const ox::FileAddress &tilesheetAddr,
|
Context *ctx,
|
||||||
const ox::FileAddress &paletteAddr) noexcept {
|
const ox::FileAddress &tilesheetAddr,
|
||||||
|
const ox::FileAddress &paletteAddr) noexcept {
|
||||||
auto &gctx = static_cast<GlContext&>(*ctx);
|
auto &gctx = static_cast<GlContext&>(*ctx);
|
||||||
auto &kctx = *gctx.turbineCtx;
|
auto &kctx = *gctx.turbineCtx;
|
||||||
oxRequire(tilesheet, readObj<CompactTileSheet>(&kctx, tilesheetAddr));
|
oxRequire(tilesheet, readObj<CompactTileSheet>(&kctx, tilesheetAddr));
|
||||||
@ -465,8 +488,8 @@ void setSprite(Context *ctx,
|
|||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
unsigned tileIdx,
|
unsigned tileIdx,
|
||||||
[[maybe_unused]] unsigned spriteShape,
|
unsigned spriteShape,
|
||||||
[[maybe_unused]] unsigned spriteSize,
|
unsigned spriteSize,
|
||||||
unsigned flipX) noexcept {
|
unsigned flipX) noexcept {
|
||||||
//oxTracef("nostalgia::core::gfx::gl", "setSprite(ctx, {}, {}, {}, {}, {}, {}, {})",
|
//oxTracef("nostalgia::core::gfx::gl", "setSprite(ctx, {}, {}, {}, {}, {}, {}, {})",
|
||||||
// idx, x, y, tileIdx, spriteShape, spriteSize, flipX);
|
// idx, x, y, tileIdx, spriteShape, spriteSize, flipX);
|
||||||
@ -519,7 +542,12 @@ void setSprite(Context *ctx,
|
|||||||
gctx.spriteBlocks.updated = true;
|
gctx.spriteBlocks.updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) noexcept {
|
void setTile(
|
||||||
|
Context *ctx,
|
||||||
|
unsigned bgIdx,
|
||||||
|
int column,
|
||||||
|
int row,
|
||||||
|
uint8_t tile) noexcept {
|
||||||
oxTracef(
|
oxTracef(
|
||||||
"nostalgia::core::gfx::setTile",
|
"nostalgia::core::gfx::setTile",
|
||||||
"bgIdx: {}, column: {}, row: {}, tile: {}",
|
"bgIdx: {}, column: {}, row: {}, tile: {}",
|
||||||
@ -546,6 +574,7 @@ void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) no
|
|||||||
namespace gl {
|
namespace gl {
|
||||||
|
|
||||||
void drawMainView(core::Context *ctx, ox::Size const&renderSz) noexcept {
|
void drawMainView(core::Context *ctx, ox::Size const&renderSz) noexcept {
|
||||||
|
glViewport(0, 0, renderSz.width, renderSz.height);
|
||||||
// clear screen
|
// clear screen
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
@ -149,7 +149,7 @@ ox::Error PaletteEditorImGui::saveItem() noexcept {
|
|||||||
const auto sctx = applicationData<studio::StudioContext>(*m_ctx);
|
const auto sctx = applicationData<studio::StudioContext>(*m_ctx);
|
||||||
oxReturnError(sctx->project->writeObj(m_itemPath, &m_pal));
|
oxReturnError(sctx->project->writeObj(m_itemPath, &m_pal));
|
||||||
oxReturnError(m_ctx->assetManager.setAsset(m_itemPath, m_pal));
|
oxReturnError(m_ctx->assetManager.setAsset(m_itemPath, m_pal));
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ ox::Error TileSheetEditorImGui::updateActiveSubsheet(const ox::String &name, int
|
|||||||
|
|
||||||
ox::Error TileSheetEditorImGui::markUnsavedChanges(const studio::UndoCommand*) noexcept {
|
ox::Error TileSheetEditorImGui::markUnsavedChanges(const studio::UndoCommand*) noexcept {
|
||||||
setUnsavedChanges(true);
|
setUnsavedChanges(true);
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorImGui::SubSheetEditor::draw() noexcept {
|
void TileSheetEditorImGui::SubSheetEditor::draw() noexcept {
|
||||||
|
@ -103,18 +103,26 @@ class DrawCommand: public TileSheetCommand {
|
|||||||
int m_palIdx = 0;
|
int m_palIdx = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr DrawCommand(TileSheet *img, const TileSheet::SubSheetIdx &subSheetIdx, std::size_t idx, int palIdx) noexcept {
|
constexpr DrawCommand(
|
||||||
m_img = img;
|
TileSheet &img,
|
||||||
auto &subsheet = m_img->getSubSheet(subSheetIdx);
|
TileSheet::SubSheetIdx subSheetIdx,
|
||||||
m_subSheetIdx = subSheetIdx;
|
std::size_t idx,
|
||||||
|
int palIdx) noexcept:
|
||||||
|
m_img(&img),
|
||||||
|
m_subSheetIdx(std::move(subSheetIdx)) {
|
||||||
|
auto &subsheet = m_img->getSubSheet(m_subSheetIdx);
|
||||||
m_changes.emplace_back(static_cast<uint32_t>(idx), subsheet.getPixel(m_img->bpp, idx));
|
m_changes.emplace_back(static_cast<uint32_t>(idx), subsheet.getPixel(m_img->bpp, idx));
|
||||||
m_palIdx = palIdx;
|
m_palIdx = palIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr DrawCommand(TileSheet *img, const TileSheet::SubSheetIdx &subSheetIdx, const ox::Vector<std::size_t> &idxList, int palIdx) noexcept {
|
constexpr DrawCommand(
|
||||||
m_img = img;
|
TileSheet &img,
|
||||||
auto &subsheet = m_img->getSubSheet(subSheetIdx);
|
TileSheet::SubSheetIdx subSheetIdx,
|
||||||
m_subSheetIdx = subSheetIdx;
|
const ox::Vector<std::size_t> &idxList,
|
||||||
|
int palIdx) noexcept:
|
||||||
|
m_img(&img),
|
||||||
|
m_subSheetIdx(std::move(subSheetIdx)) {
|
||||||
|
auto &subsheet = m_img->getSubSheet(m_subSheetIdx);
|
||||||
for (const auto idx : idxList) {
|
for (const auto idx : idxList) {
|
||||||
m_changes.emplace_back(static_cast<uint32_t>(idx), subsheet.getPixel(m_img->bpp, idx));
|
m_changes.emplace_back(static_cast<uint32_t>(idx), subsheet.getPixel(m_img->bpp, idx));
|
||||||
}
|
}
|
||||||
@ -123,7 +131,7 @@ class DrawCommand: public TileSheetCommand {
|
|||||||
|
|
||||||
constexpr auto append(std::size_t idx) noexcept {
|
constexpr auto append(std::size_t idx) noexcept {
|
||||||
auto &subsheet = m_img->getSubSheet(m_subSheetIdx);
|
auto &subsheet = m_img->getSubSheet(m_subSheetIdx);
|
||||||
if (m_changes.back().value.idx != idx && subsheet.getPixel(m_img->bpp, idx) != m_palIdx) {
|
if (m_changes.back().value->idx != idx && subsheet.getPixel(m_img->bpp, idx) != m_palIdx) {
|
||||||
// duplicate entries are bad
|
// duplicate entries are bad
|
||||||
auto existing = ox::find_if(m_changes.cbegin(), m_changes.cend(), [idx](const auto &c) {
|
auto existing = ox::find_if(m_changes.cbegin(), m_changes.cend(), [idx](const auto &c) {
|
||||||
return c.idx == idx;
|
return c.idx == idx;
|
||||||
@ -184,35 +192,40 @@ class CutPasteCommand: public TileSheetCommand {
|
|||||||
oldPalIdx = pOldPalIdx;
|
oldPalIdx = pOldPalIdx;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet &m_img;
|
||||||
TileSheet::SubSheetIdx m_subSheetIdx;
|
TileSheet::SubSheetIdx m_subSheetIdx;
|
||||||
ox::Vector<Change> m_changes;
|
ox::Vector<Change> m_changes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr CutPasteCommand(TileSheet *img, const TileSheet::SubSheetIdx &subSheetIdx, const ox::Point &dstStart, const ox::Point &dstEnd, const TileSheetClipboard &cb) noexcept {
|
constexpr CutPasteCommand(
|
||||||
m_img = img;
|
TileSheet &img,
|
||||||
m_subSheetIdx = subSheetIdx;
|
TileSheet::SubSheetIdx subSheetIdx,
|
||||||
const auto &subsheet = m_img->getSubSheet(subSheetIdx);
|
const ox::Point &dstStart,
|
||||||
|
const ox::Point &dstEnd,
|
||||||
|
const TileSheetClipboard &cb) noexcept:
|
||||||
|
m_img(img),
|
||||||
|
m_subSheetIdx(std::move(subSheetIdx)) {
|
||||||
|
const auto &subsheet = m_img.getSubSheet(m_subSheetIdx);
|
||||||
for (const auto &p : cb.pixels()) {
|
for (const auto &p : cb.pixels()) {
|
||||||
const auto dstPt = p.pt + dstStart;
|
const auto dstPt = p.pt + dstStart;
|
||||||
if (dstPt.x <= dstEnd.x && dstPt.y <= dstEnd.y) {
|
if (dstPt.x <= dstEnd.x && dstPt.y <= dstEnd.y) {
|
||||||
const auto idx = subsheet.idx(dstPt);
|
const auto idx = subsheet.idx(dstPt);
|
||||||
m_changes.emplace_back(static_cast<uint32_t>(idx), p.colorIdx, subsheet.getPixel(m_img->bpp, idx));
|
m_changes.emplace_back(static_cast<uint32_t>(idx), p.colorIdx, subsheet.getPixel(m_img.bpp, idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void redo() noexcept final {
|
void redo() noexcept final {
|
||||||
auto &subsheet = m_img->getSubSheet(m_subSheetIdx);
|
auto &subsheet = m_img.getSubSheet(m_subSheetIdx);
|
||||||
for (const auto &c : m_changes) {
|
for (const auto &c : m_changes) {
|
||||||
subsheet.setPixel(m_img->bpp, c.idx, static_cast<uint8_t>(c.newPalIdx));
|
subsheet.setPixel(m_img.bpp, c.idx, static_cast<uint8_t>(c.newPalIdx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo() noexcept final {
|
void undo() noexcept final {
|
||||||
auto &subsheet = m_img->getSubSheet(m_subSheetIdx);
|
auto &subsheet = m_img.getSubSheet(m_subSheetIdx);
|
||||||
for (const auto &c : m_changes) {
|
for (const auto &c : m_changes) {
|
||||||
subsheet.setPixel(m_img->bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx));
|
subsheet.setPixel(m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,15 +243,15 @@ class CutPasteCommand: public TileSheetCommand {
|
|||||||
|
|
||||||
class AddSubSheetCommand: public TileSheetCommand {
|
class AddSubSheetCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet &m_img;
|
||||||
TileSheet::SubSheetIdx m_parentIdx;
|
TileSheet::SubSheetIdx m_parentIdx;
|
||||||
ox::Vector<TileSheet::SubSheetIdx, 2> m_addedSheets;
|
ox::Vector<TileSheet::SubSheetIdx, 2> m_addedSheets;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr AddSubSheetCommand(TileSheet *img, const TileSheet::SubSheetIdx &parentIdx) noexcept {
|
constexpr AddSubSheetCommand(TileSheet &img, TileSheet::SubSheetIdx parentIdx) noexcept:
|
||||||
m_img = img;
|
m_img(img),
|
||||||
m_parentIdx = parentIdx;
|
m_parentIdx(std::move(parentIdx)) {
|
||||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||||
if (parent.subsheets.size()) {
|
if (parent.subsheets.size()) {
|
||||||
auto idx = m_parentIdx;
|
auto idx = m_parentIdx;
|
||||||
idx.emplace_back(parent.subsheets.size());
|
idx.emplace_back(parent.subsheets.size());
|
||||||
@ -247,26 +260,26 @@ class AddSubSheetCommand: public TileSheetCommand {
|
|||||||
auto idx = m_parentIdx;
|
auto idx = m_parentIdx;
|
||||||
idx.emplace_back(0u);
|
idx.emplace_back(0u);
|
||||||
m_addedSheets.push_back(idx);
|
m_addedSheets.push_back(idx);
|
||||||
idx.back().value = 1;
|
*idx.back().value = 1;
|
||||||
m_addedSheets.push_back(idx);
|
m_addedSheets.push_back(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void redo() noexcept final {
|
void redo() noexcept final {
|
||||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||||
if (m_addedSheets.size() < 2) {
|
if (m_addedSheets.size() < 2) {
|
||||||
auto i = parent.subsheets.size();
|
auto i = parent.subsheets.size();
|
||||||
parent.subsheets.emplace_back(m_img->idIt++, ox::sfmt("Subsheet {}", i), 1, 1, m_img->bpp);
|
parent.subsheets.emplace_back(m_img.idIt++, ox::sfmt("Subsheet {}", i), 1, 1, m_img.bpp);
|
||||||
} else {
|
} else {
|
||||||
parent.subsheets.emplace_back(m_img->idIt++, "Subsheet 0", parent.columns, parent.rows, std::move(parent.pixels));
|
parent.subsheets.emplace_back(m_img.idIt++, "Subsheet 0", parent.columns, parent.rows, std::move(parent.pixels));
|
||||||
parent.rows = 0;
|
parent.rows = 0;
|
||||||
parent.columns = 0;
|
parent.columns = 0;
|
||||||
parent.subsheets.emplace_back(m_img->idIt++, "Subsheet 1", 1, 1, m_img->bpp);
|
parent.subsheets.emplace_back(m_img.idIt++, "Subsheet 1", 1, 1, m_img.bpp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo() noexcept final {
|
void undo() noexcept final {
|
||||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||||
if (parent.subsheets.size() == 2) {
|
if (parent.subsheets.size() == 2) {
|
||||||
auto s = parent.subsheets[0];
|
auto s = parent.subsheets[0];
|
||||||
parent.rows = s.rows;
|
parent.rows = s.rows;
|
||||||
@ -275,7 +288,7 @@ class AddSubSheetCommand: public TileSheetCommand {
|
|||||||
parent.subsheets.clear();
|
parent.subsheets.clear();
|
||||||
} else {
|
} else {
|
||||||
for (auto idx = m_addedSheets.rbegin(); idx != m_addedSheets.rend(); ++idx) {
|
for (auto idx = m_addedSheets.rbegin(); idx != m_addedSheets.rend(); ++idx) {
|
||||||
oxLogError(m_img->rmSubSheet(*idx));
|
oxLogError(m_img.rmSubSheet(*idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,29 +307,29 @@ class AddSubSheetCommand: public TileSheetCommand {
|
|||||||
|
|
||||||
class RmSubSheetCommand: public TileSheetCommand {
|
class RmSubSheetCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet &m_img;
|
||||||
TileSheet::SubSheetIdx m_idx;
|
TileSheet::SubSheetIdx m_idx;
|
||||||
TileSheet::SubSheetIdx m_parentIdx;
|
TileSheet::SubSheetIdx m_parentIdx;
|
||||||
TileSheet::SubSheet m_sheet;
|
TileSheet::SubSheet m_sheet;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr RmSubSheetCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx) noexcept {
|
constexpr RmSubSheetCommand(TileSheet &img, TileSheet::SubSheetIdx idx) noexcept:
|
||||||
m_img = img;
|
m_img(img),
|
||||||
m_idx = idx;
|
m_idx(std::move(idx)) {
|
||||||
m_parentIdx = idx;
|
m_parentIdx = idx;
|
||||||
m_parentIdx.pop_back();
|
m_parentIdx.pop_back();
|
||||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||||
m_sheet = parent.subsheets[idx.back().value];
|
m_sheet = parent.subsheets[*idx.back().value];
|
||||||
}
|
}
|
||||||
|
|
||||||
void redo() noexcept final {
|
void redo() noexcept final {
|
||||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||||
oxLogError(parent.subsheets.erase(m_idx.back().value).error);
|
oxLogError(parent.subsheets.erase(*m_idx.back().value).error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo() noexcept final {
|
void undo() noexcept final {
|
||||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||||
auto i = m_idx.back().value;
|
auto i = *m_idx.back().value;
|
||||||
parent.subsheets.insert(i, m_sheet);
|
parent.subsheets.insert(i, m_sheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,23 +347,27 @@ class RmSubSheetCommand: public TileSheetCommand {
|
|||||||
|
|
||||||
class InsertTilesCommand: public TileSheetCommand {
|
class InsertTilesCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet &m_img;
|
||||||
TileSheet::SubSheetIdx m_idx;
|
TileSheet::SubSheetIdx m_idx;
|
||||||
std::size_t m_insertPos = 0;
|
std::size_t m_insertPos = 0;
|
||||||
std::size_t m_insertCnt = 0;
|
std::size_t m_insertCnt = 0;
|
||||||
ox::Vector<uint8_t> m_deletedPixels = {};
|
ox::Vector<uint8_t> m_deletedPixels = {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr InsertTilesCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
constexpr InsertTilesCommand(
|
||||||
const unsigned bytesPerTile = img->bpp == 4 ? PixelsPerTile / 2 : PixelsPerTile;
|
TileSheet &img,
|
||||||
m_img = img;
|
TileSheet::SubSheetIdx idx,
|
||||||
m_idx = idx;
|
std::size_t tileIdx,
|
||||||
|
std::size_t tileCnt) noexcept:
|
||||||
|
m_img(img),
|
||||||
|
m_idx(std::move(idx)) {
|
||||||
|
const unsigned bytesPerTile = m_img.bpp == 4 ? PixelsPerTile / 2 : PixelsPerTile;
|
||||||
m_insertPos = tileIdx * bytesPerTile;
|
m_insertPos = tileIdx * bytesPerTile;
|
||||||
m_insertCnt = tileCnt * bytesPerTile;
|
m_insertCnt = tileCnt * bytesPerTile;
|
||||||
m_deletedPixels.resize(m_insertCnt);
|
m_deletedPixels.resize(m_insertCnt);
|
||||||
// copy pixels to be erased
|
// copy pixels to be erased
|
||||||
{
|
{
|
||||||
auto &s = m_img->getSubSheet(m_idx);
|
auto &s = m_img.getSubSheet(m_idx);
|
||||||
auto &p = s.pixels;
|
auto &p = s.pixels;
|
||||||
auto dst = m_deletedPixels.data();
|
auto dst = m_deletedPixels.data();
|
||||||
auto src = p.data() + p.size() - m_insertCnt;
|
auto src = p.data() + p.size() - m_insertCnt;
|
||||||
@ -360,7 +377,7 @@ class InsertTilesCommand: public TileSheetCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void redo() noexcept final {
|
void redo() noexcept final {
|
||||||
auto &s = m_img->getSubSheet(m_idx);
|
auto &s = m_img.getSubSheet(m_idx);
|
||||||
auto &p = s.pixels;
|
auto &p = s.pixels;
|
||||||
auto dstPos = m_insertPos + m_insertCnt;
|
auto dstPos = m_insertPos + m_insertCnt;
|
||||||
const auto dst = p.data() + dstPos;
|
const auto dst = p.data() + dstPos;
|
||||||
@ -370,7 +387,7 @@ class InsertTilesCommand: public TileSheetCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void undo() noexcept final {
|
void undo() noexcept final {
|
||||||
auto &s = m_img->getSubSheet(m_idx);
|
auto &s = m_img.getSubSheet(m_idx);
|
||||||
auto &p = s.pixels;
|
auto &p = s.pixels;
|
||||||
const auto srcIdx = m_insertPos + m_insertCnt;
|
const auto srcIdx = m_insertPos + m_insertCnt;
|
||||||
const auto src = p.data() + srcIdx;
|
const auto src = p.data() + srcIdx;
|
||||||
@ -395,23 +412,27 @@ class InsertTilesCommand: public TileSheetCommand {
|
|||||||
|
|
||||||
class DeleteTilesCommand: public TileSheetCommand {
|
class DeleteTilesCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet &m_img;
|
||||||
TileSheet::SubSheetIdx m_idx;
|
TileSheet::SubSheetIdx m_idx;
|
||||||
std::size_t m_deletePos = 0;
|
std::size_t m_deletePos = 0;
|
||||||
std::size_t m_deleteSz = 0;
|
std::size_t m_deleteSz = 0;
|
||||||
ox::Vector<uint8_t> m_deletedPixels = {};
|
ox::Vector<uint8_t> m_deletedPixels = {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr DeleteTilesCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
constexpr DeleteTilesCommand(
|
||||||
const unsigned bytesPerTile = img->bpp == 4 ? PixelsPerTile / 2 : PixelsPerTile;
|
TileSheet &img,
|
||||||
m_img = img;
|
TileSheet::SubSheetIdx idx,
|
||||||
m_idx = idx;
|
std::size_t tileIdx,
|
||||||
|
std::size_t tileCnt) noexcept:
|
||||||
|
m_img(img),
|
||||||
|
m_idx(std::move(idx)) {
|
||||||
|
const unsigned bytesPerTile = m_img.bpp == 4 ? PixelsPerTile / 2 : PixelsPerTile;
|
||||||
m_deletePos = tileIdx * bytesPerTile;
|
m_deletePos = tileIdx * bytesPerTile;
|
||||||
m_deleteSz = tileCnt * bytesPerTile;
|
m_deleteSz = tileCnt * bytesPerTile;
|
||||||
m_deletedPixels.resize(m_deleteSz);
|
m_deletedPixels.resize(m_deleteSz);
|
||||||
// copy pixels to be erased
|
// copy pixels to be erased
|
||||||
{
|
{
|
||||||
auto &s = m_img->getSubSheet(m_idx);
|
auto &s = m_img.getSubSheet(m_idx);
|
||||||
auto &p = s.pixels;
|
auto &p = s.pixels;
|
||||||
auto dst = m_deletedPixels.data();
|
auto dst = m_deletedPixels.data();
|
||||||
auto src = p.data() + m_deletePos;
|
auto src = p.data() + m_deletePos;
|
||||||
@ -421,7 +442,7 @@ class DeleteTilesCommand: public TileSheetCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void redo() noexcept final {
|
void redo() noexcept final {
|
||||||
auto &s = m_img->getSubSheet(m_idx);
|
auto &s = m_img.getSubSheet(m_idx);
|
||||||
auto &p = s.pixels;
|
auto &p = s.pixels;
|
||||||
auto srcPos = m_deletePos + m_deleteSz;
|
auto srcPos = m_deletePos + m_deleteSz;
|
||||||
const auto src = p.data() + srcPos;
|
const auto src = p.data() + srcPos;
|
||||||
@ -432,7 +453,7 @@ class DeleteTilesCommand: public TileSheetCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void undo() noexcept final {
|
void undo() noexcept final {
|
||||||
auto &s = m_img->getSubSheet(m_idx);
|
auto &s = m_img.getSubSheet(m_idx);
|
||||||
auto &p = s.pixels;
|
auto &p = s.pixels;
|
||||||
const auto src = p.data() + m_deletePos;
|
const auto src = p.data() + m_deletePos;
|
||||||
const auto dst1 = p.data() + m_deletePos + m_deleteSz;
|
const auto dst1 = p.data() + m_deletePos + m_deleteSz;
|
||||||
@ -456,7 +477,7 @@ class DeleteTilesCommand: public TileSheetCommand {
|
|||||||
|
|
||||||
class UpdateSubSheetCommand: public TileSheetCommand {
|
class UpdateSubSheetCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
TileSheet *m_img = nullptr;
|
TileSheet &m_img;
|
||||||
TileSheet::SubSheetIdx m_idx;
|
TileSheet::SubSheetIdx m_idx;
|
||||||
TileSheet::SubSheet m_sheet;
|
TileSheet::SubSheet m_sheet;
|
||||||
ox::String m_newName;
|
ox::String m_newName;
|
||||||
@ -464,26 +485,30 @@ class UpdateSubSheetCommand: public TileSheetCommand {
|
|||||||
int m_newRows = 0;
|
int m_newRows = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr UpdateSubSheetCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx,
|
constexpr UpdateSubSheetCommand(
|
||||||
const ox::String &name, int cols, int rows) noexcept {
|
TileSheet &img,
|
||||||
m_img = img;
|
TileSheet::SubSheetIdx idx,
|
||||||
m_idx = idx;
|
const ox::String &name,
|
||||||
m_sheet = img->getSubSheet(idx);
|
int cols,
|
||||||
|
int rows) noexcept:
|
||||||
|
m_img(img),
|
||||||
|
m_idx(std::move(idx)) {
|
||||||
|
m_sheet = m_img.getSubSheet(m_idx);
|
||||||
m_newName = name;
|
m_newName = name;
|
||||||
m_newCols = cols;
|
m_newCols = cols;
|
||||||
m_newRows = rows;
|
m_newRows = rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
void redo() noexcept final {
|
void redo() noexcept final {
|
||||||
auto &sheet = m_img->getSubSheet(m_idx);
|
auto &sheet = m_img.getSubSheet(m_idx);
|
||||||
sheet.name = m_newName;
|
sheet.name = m_newName;
|
||||||
sheet.columns = m_newCols;
|
sheet.columns = m_newCols;
|
||||||
sheet.rows = m_newRows;
|
sheet.rows = m_newRows;
|
||||||
oxLogError(sheet.setPixelCount(m_img->bpp, static_cast<std::size_t>(PixelsPerTile * m_newCols * m_newRows)));
|
oxLogError(sheet.setPixelCount(m_img.bpp, static_cast<std::size_t>(PixelsPerTile * m_newCols * m_newRows)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo() noexcept final {
|
void undo() noexcept final {
|
||||||
auto &sheet = m_img->getSubSheet(m_idx);
|
auto &sheet = m_img.getSubSheet(m_idx);
|
||||||
sheet = m_sheet;
|
sheet = m_sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,25 +526,28 @@ class UpdateSubSheetCommand: public TileSheetCommand {
|
|||||||
|
|
||||||
class PaletteChangeCommand: public TileSheetCommand {
|
class PaletteChangeCommand: public TileSheetCommand {
|
||||||
private:
|
private:
|
||||||
|
TileSheet &m_img;
|
||||||
TileSheet::SubSheetIdx m_idx;
|
TileSheet::SubSheetIdx m_idx;
|
||||||
TileSheet *m_img = nullptr;
|
|
||||||
ox::FileAddress m_oldPalette;
|
ox::FileAddress m_oldPalette;
|
||||||
ox::FileAddress m_newPalette;
|
ox::FileAddress m_newPalette;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PaletteChangeCommand(const TileSheet::SubSheetIdx &idx, TileSheet *img, ox::CRStringView newPalette) noexcept {
|
PaletteChangeCommand(
|
||||||
m_idx = idx;
|
TileSheet::SubSheetIdx idx,
|
||||||
m_img = img;
|
TileSheet &img,
|
||||||
m_oldPalette = m_img->defaultPalette;
|
ox::CRStringView newPalette) noexcept:
|
||||||
|
m_img(img),
|
||||||
|
m_idx(std::move(idx)) {
|
||||||
|
m_oldPalette = m_img.defaultPalette;
|
||||||
m_newPalette = ox::FileAddress(ox::sfmt<ox::BString<43>>("uuid://{}", newPalette));
|
m_newPalette = ox::FileAddress(ox::sfmt<ox::BString<43>>("uuid://{}", newPalette));
|
||||||
}
|
}
|
||||||
|
|
||||||
void redo() noexcept final {
|
void redo() noexcept final {
|
||||||
m_img->defaultPalette = m_newPalette;
|
m_img.defaultPalette = m_newPalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo() noexcept final {
|
void undo() noexcept final {
|
||||||
m_img->defaultPalette = m_oldPalette;
|
m_img.defaultPalette = m_oldPalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
@ -535,9 +563,9 @@ class PaletteChangeCommand: public TileSheetCommand {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TileSheetEditorModel::TileSheetEditorModel(turbine::Context *ctx, ox::String path) {
|
TileSheetEditorModel::TileSheetEditorModel(turbine::Context *ctx, ox::String path):
|
||||||
m_ctx = ctx;
|
m_ctx(ctx),
|
||||||
m_path = std::move(path);
|
m_path(std::move(path)) {
|
||||||
oxRequireT(img, readObj<TileSheet>(ctx, m_path));
|
oxRequireT(img, readObj<TileSheet>(ctx, m_path));
|
||||||
m_img = *img;
|
m_img = *img;
|
||||||
if (m_img.defaultPalette) {
|
if (m_img.defaultPalette) {
|
||||||
@ -565,7 +593,7 @@ void TileSheetEditorModel::cut() {
|
|||||||
const auto pt1 = m_selectionOrigin == ox::Point(-1, -1) ? ox::Point(0, 0) : m_selectionOrigin;
|
const auto pt1 = m_selectionOrigin == ox::Point(-1, -1) ? ox::Point(0, 0) : m_selectionOrigin;
|
||||||
const auto pt2 = ox::Point(s->columns * TileWidth, s->rows * TileHeight);
|
const auto pt2 = ox::Point(s->columns * TileWidth, s->rows * TileHeight);
|
||||||
turbine::setClipboardObject(*m_ctx, std::move(cb));
|
turbine::setClipboardObject(*m_ctx, std::move(cb));
|
||||||
pushCommand(ox::make<CutPasteCommand<CommandId::Cut>>(&m_img, m_activeSubsSheetIdx, pt1, pt2, blankCb));
|
pushCommand(ox::make<CutPasteCommand<CommandId::Cut>>(m_img, m_activeSubsSheetIdx, pt1, pt2, blankCb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::copy() {
|
void TileSheetEditorModel::copy() {
|
||||||
@ -594,7 +622,7 @@ void TileSheetEditorModel::paste() {
|
|||||||
const auto s = activeSubSheet();
|
const auto s = activeSubSheet();
|
||||||
const auto pt1 = m_selectionOrigin == ox::Point(-1, -1) ? ox::Point(0, 0) : m_selectionOrigin;
|
const auto pt1 = m_selectionOrigin == ox::Point(-1, -1) ? ox::Point(0, 0) : m_selectionOrigin;
|
||||||
const auto pt2 = ox::Point(s->columns * TileWidth, s->rows * TileHeight);
|
const auto pt2 = ox::Point(s->columns * TileWidth, s->rows * TileHeight);
|
||||||
pushCommand(ox::make<CutPasteCommand<CommandId::Paste>>(&m_img, m_activeSubsSheetIdx, pt1, pt2, *cb));
|
pushCommand(ox::make<CutPasteCommand<CommandId::Paste>>(m_img, m_activeSubsSheetIdx, pt1, pt2, *cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::StringView TileSheetEditorModel::palPath() const noexcept {
|
ox::StringView TileSheetEditorModel::palPath() const noexcept {
|
||||||
@ -617,8 +645,8 @@ ox::StringView TileSheetEditorModel::palPath() const noexcept {
|
|||||||
|
|
||||||
ox::Error TileSheetEditorModel::setPalette(const ox::String &path) noexcept {
|
ox::Error TileSheetEditorModel::setPalette(const ox::String &path) noexcept {
|
||||||
oxRequire(uuid, m_ctx->pathToUuid.at(path));
|
oxRequire(uuid, m_ctx->pathToUuid.at(path));
|
||||||
pushCommand(ox::make<PaletteChangeCommand>(activeSubSheetIdx(), &m_img, uuid->toString()));
|
pushCommand(ox::make<PaletteChangeCommand>(activeSubSheetIdx(), m_img, uuid->toString()));
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::drawCommand(const ox::Point &pt, std::size_t palIdx) noexcept {
|
void TileSheetEditorModel::drawCommand(const ox::Point &pt, std::size_t palIdx) noexcept {
|
||||||
@ -630,7 +658,7 @@ void TileSheetEditorModel::drawCommand(const ox::Point &pt, std::size_t palIdx)
|
|||||||
if (m_ongoingDrawCommand) {
|
if (m_ongoingDrawCommand) {
|
||||||
m_updated = m_updated || m_ongoingDrawCommand->append(idx);
|
m_updated = m_updated || m_ongoingDrawCommand->append(idx);
|
||||||
} else if (activeSubSheet.getPixel(m_img.bpp, idx) != palIdx) {
|
} else if (activeSubSheet.getPixel(m_img.bpp, idx) != palIdx) {
|
||||||
pushCommand(ox::make<DrawCommand>(&m_img, m_activeSubsSheetIdx, idx, static_cast<int>(palIdx)));
|
pushCommand(ox::make<DrawCommand>(m_img, m_activeSubsSheetIdx, idx, static_cast<int>(palIdx)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,24 +667,24 @@ void TileSheetEditorModel::endDrawCommand() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::addSubsheet(const TileSheet::SubSheetIdx &parentIdx) noexcept {
|
void TileSheetEditorModel::addSubsheet(const TileSheet::SubSheetIdx &parentIdx) noexcept {
|
||||||
pushCommand(ox::make<AddSubSheetCommand>(&m_img, parentIdx));
|
pushCommand(ox::make<AddSubSheetCommand>(m_img, parentIdx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::rmSubsheet(const TileSheet::SubSheetIdx &idx) noexcept {
|
void TileSheetEditorModel::rmSubsheet(const TileSheet::SubSheetIdx &idx) noexcept {
|
||||||
pushCommand(ox::make<RmSubSheetCommand>(&m_img, idx));
|
pushCommand(ox::make<RmSubSheetCommand>(m_img, idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::insertTiles(const TileSheet::SubSheetIdx &idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
void TileSheetEditorModel::insertTiles(const TileSheet::SubSheetIdx &idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
||||||
pushCommand(ox::make<InsertTilesCommand>(&m_img, idx, tileIdx, tileCnt));
|
pushCommand(ox::make<InsertTilesCommand>(m_img, idx, tileIdx, tileCnt));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::deleteTiles(const TileSheet::SubSheetIdx &idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
void TileSheetEditorModel::deleteTiles(const TileSheet::SubSheetIdx &idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
||||||
pushCommand(ox::make<DeleteTilesCommand>(&m_img, idx, tileIdx, tileCnt));
|
pushCommand(ox::make<DeleteTilesCommand>(m_img, idx, tileIdx, tileCnt));
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::updateSubsheet(const TileSheet::SubSheetIdx &idx, const ox::String &name, int cols, int rows) noexcept {
|
ox::Error TileSheetEditorModel::updateSubsheet(const TileSheet::SubSheetIdx &idx, const ox::String &name, int cols, int rows) noexcept {
|
||||||
pushCommand(ox::make<UpdateSubSheetCommand>(&m_img, idx, name, cols, rows));
|
pushCommand(ox::make<UpdateSubSheetCommand>(m_img, idx, name, cols, rows));
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::setActiveSubsheet(const TileSheet::SubSheetIdx &idx) noexcept {
|
void TileSheetEditorModel::setActiveSubsheet(const TileSheet::SubSheetIdx &idx) noexcept {
|
||||||
@ -685,7 +713,7 @@ void TileSheetEditorModel::fill(const ox::Point &pt, int palIdx) noexcept {
|
|||||||
if (m_ongoingDrawCommand) {
|
if (m_ongoingDrawCommand) {
|
||||||
m_updated = m_updated || m_ongoingDrawCommand->append(idxList);
|
m_updated = m_updated || m_ongoingDrawCommand->append(idxList);
|
||||||
} else if (s.getPixel(m_img.bpp, pt) != palIdx) {
|
} else if (s.getPixel(m_img.bpp, pt) != palIdx) {
|
||||||
pushCommand(ox::make<DrawCommand>(&m_img, m_activeSubsSheetIdx, idxList, palIdx));
|
pushCommand(ox::make<DrawCommand>(m_img, m_activeSubsSheetIdx, idxList, palIdx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,12 +759,12 @@ ox::Error TileSheetEditorModel::markUpdatedCmdId(const studio::UndoCommand *cmd)
|
|||||||
if (idx != m_activeSubsSheetIdx) {
|
if (idx != m_activeSubsSheetIdx) {
|
||||||
setActiveSubsheet(idx);
|
setActiveSubsheet(idx);
|
||||||
}
|
}
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::markUpdated() noexcept {
|
ox::Error TileSheetEditorModel::markUpdated() noexcept {
|
||||||
m_updated = true;
|
m_updated = true;
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::ackUpdate() noexcept {
|
void TileSheetEditorModel::ackUpdate() noexcept {
|
||||||
|
@ -97,7 +97,7 @@ bool TileSheetEditorView::updated() const noexcept {
|
|||||||
|
|
||||||
ox::Error TileSheetEditorView::markUpdated() noexcept {
|
ox::Error TileSheetEditorView::markUpdated() noexcept {
|
||||||
m_updated = true;
|
m_updated = true;
|
||||||
return OxError(0);
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorView::ackUpdate() noexcept {
|
void TileSheetEditorView::ackUpdate() noexcept {
|
||||||
|
@ -387,7 +387,7 @@ struct TileSheet {
|
|||||||
if (pSubsheet->subsheets.size() <= currentIdx) {
|
if (pSubsheet->subsheets.size() <= currentIdx) {
|
||||||
auto out = pIdx;
|
auto out = pIdx;
|
||||||
if (!pSubsheet->subsheets.empty()) {
|
if (!pSubsheet->subsheets.empty()) {
|
||||||
out.back().value = pSubsheet->subsheets.size() - 1;
|
*out.back().value = pSubsheet->subsheets.size() - 1;
|
||||||
} else {
|
} else {
|
||||||
out.pop_back();
|
out.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,7 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab)
|
|||||||
m_editors.emplace_back(editor);
|
m_editors.emplace_back(editor);
|
||||||
m_openFiles.emplace_back(path);
|
m_openFiles.emplace_back(path);
|
||||||
if (makeActiveTab) {
|
if (makeActiveTab) {
|
||||||
m_activeEditor = m_editors.back().value.get();
|
m_activeEditor = m_editors.back().value->get();
|
||||||
m_activeEditorUpdatePending = editor;
|
m_activeEditorUpdatePending = editor;
|
||||||
}
|
}
|
||||||
// save to config
|
// save to config
|
||||||
|
@ -49,7 +49,7 @@ ox::Error writeConfig(keel::Context *ctx, ox::CRStringView name, T *data) noexce
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
oxRequireM(buff, ox::writeOC(*data));
|
oxRequireM(buff, ox::writeOC(*data));
|
||||||
buff.back().value = '\n';
|
*buff.back().value = '\n';
|
||||||
if (const auto err = fs.write(path, buff.data(), buff.size())) {
|
if (const auto err = fs.write(path, buff.data(), buff.size())) {
|
||||||
oxErrf("Could not read config file: {}\n", toStr(err));
|
oxErrf("Could not read config file: {}\n", toStr(err));
|
||||||
return OxError(2, "Could not read config file");
|
return OxError(2, "Could not read config file");
|
||||||
|
@ -120,7 +120,7 @@ ox::Error Project::writeObj(const ox::StringView &path, const T *obj, ox::ClawFo
|
|||||||
for (const auto &t : m_typeStore.typeList()) {
|
for (const auto &t : m_typeStore.typeList()) {
|
||||||
oxRequireM(typeOut, ox::writeClaw(*t, ox::ClawFormat::Organic));
|
oxRequireM(typeOut, ox::writeClaw(*t, ox::ClawFormat::Organic));
|
||||||
// replace garbage last character with new line
|
// replace garbage last character with new line
|
||||||
typeOut.back().value = '\n';
|
*typeOut.back().value = '\n';
|
||||||
// write to FS
|
// write to FS
|
||||||
const auto typePath = ox::sfmt("/{}/{}", descPath, buildTypeId(*t));
|
const auto typePath = ox::sfmt("/{}/{}", descPath, buildTypeId(*t));
|
||||||
oxReturnError(writeBuff(typePath, typeOut));
|
oxReturnError(writeBuff(typePath, typeOut));
|
||||||
|
@ -17,7 +17,7 @@ void UndoStack::push(UndoCommand *cmd) noexcept {
|
|||||||
cmd->redo();
|
cmd->redo();
|
||||||
redoTriggered.emit(cmd);
|
redoTriggered.emit(cmd);
|
||||||
changeTriggered.emit(cmd);
|
changeTriggered.emit(cmd);
|
||||||
if (!m_stack.size() || !m_stack.back().value->mergeWith(cmd)) {
|
if (!m_stack.size() || !(*m_stack.back().value)->mergeWith(cmd)) {
|
||||||
m_stack.emplace_back(cmd);
|
m_stack.emplace_back(cmd);
|
||||||
++m_stackIdx;
|
++m_stackIdx;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user