[nostalgia,studio] Update for Ox changes, cleanup
This commit is contained in:
parent
dde51151ff
commit
ba50b083ff
@ -17,12 +17,6 @@
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
namespace gl {
|
||||
|
||||
void drawMainView(core::Context *ctx, ox::Size const&renderSz) noexcept;
|
||||
|
||||
}
|
||||
|
||||
namespace renderer {
|
||||
|
||||
void Drawer::draw(turbine::Context &tctx) noexcept {
|
||||
@ -79,14 +73,16 @@ static constexpr auto bgVertexRow(unsigned x, unsigned y) noexcept {
|
||||
return y * TileRows + x;
|
||||
}
|
||||
|
||||
static void setSpriteBufferObject(Context*,
|
||||
unsigned vi,
|
||||
float enabled,
|
||||
float x, float y,
|
||||
unsigned textureRow,
|
||||
unsigned flipX,
|
||||
float *vbo,
|
||||
GLuint *ebo) noexcept {
|
||||
static void setSpriteBufferObject(
|
||||
Context*,
|
||||
unsigned vi,
|
||||
float enabled,
|
||||
float x,
|
||||
float y,
|
||||
unsigned textureRow,
|
||||
unsigned flipX,
|
||||
float *vbo,
|
||||
GLuint *ebo) noexcept {
|
||||
// don't worry, this memcpy gets optimized to something much more ideal
|
||||
constexpr float xmod = 0.1f;
|
||||
constexpr float ymod = 0.1f;
|
||||
@ -111,13 +107,14 @@ static void setSpriteBufferObject(Context*,
|
||||
memcpy(ebo, elms.data(), sizeof(elms));
|
||||
}
|
||||
|
||||
static void setTileBufferObject(Context*,
|
||||
unsigned vi,
|
||||
float x,
|
||||
float y,
|
||||
unsigned textureRow,
|
||||
float *vbo,
|
||||
GLuint *ebo) noexcept {
|
||||
static void setTileBufferObject(
|
||||
Context*,
|
||||
unsigned vi,
|
||||
float x,
|
||||
float y,
|
||||
unsigned textureRow,
|
||||
float *vbo,
|
||||
GLuint *ebo) noexcept {
|
||||
// don't worry, this memcpy gets optimized to something much more ideal
|
||||
constexpr float ymod = 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
|
||||
bs->vao = glutils::generateVertexArrayObject();
|
||||
glBindVertexArray(bs->vao);
|
||||
@ -190,7 +188,10 @@ static void initSpritesBufferset(Context *ctx, GLuint shader, glutils::BufferSet
|
||||
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
|
||||
bg->vao = glutils::generateVertexArrayObject();
|
||||
glBindVertexArray(bg->vao);
|
||||
@ -210,7 +211,10 @@ static void initBackgroundBufferset(Context *ctx, GLuint shader, glutils::Buffer
|
||||
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;
|
||||
glGenTextures(1, &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);
|
||||
}
|
||||
|
||||
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
|
||||
glUseProgram(gctx->bgShader);
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
ox::Array<GLfloat, ColorCnt * 4> palette{};
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
const auto bgVshad = ox::sfmt(renderer::bgvshadTmpl, glutils::GlslVersion);
|
||||
@ -355,7 +375,8 @@ struct TileSheetData {
|
||||
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);
|
||||
const unsigned bytesPerTile = tilesheet.bpp == 8 ? PixelsPerTile : PixelsPerTile / 2;
|
||||
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};
|
||||
}
|
||||
|
||||
ox::Error loadBgTileSheet(Context *ctx,
|
||||
unsigned cbb,
|
||||
const ox::FileAddress &tilesheetAddr,
|
||||
const ox::FileAddress &paletteAddr) noexcept {
|
||||
ox::Error loadBgTileSheet(
|
||||
Context *ctx,
|
||||
unsigned cbb,
|
||||
const ox::FileAddress &tilesheetAddr,
|
||||
const ox::FileAddress &paletteAddr) noexcept {
|
||||
auto &gctx = static_cast<GlContext&>(*ctx);
|
||||
auto &kctx = *gctx.turbineCtx;
|
||||
oxRequire(tilesheet, readObj<CompactTileSheet>(&kctx, tilesheetAddr));
|
||||
@ -392,9 +414,10 @@ ox::Error loadBgTileSheet(Context *ctx,
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error loadSpriteTileSheet(Context *ctx,
|
||||
const ox::FileAddress &tilesheetAddr,
|
||||
const ox::FileAddress &paletteAddr) noexcept {
|
||||
ox::Error loadSpriteTileSheet(
|
||||
Context *ctx,
|
||||
const ox::FileAddress &tilesheetAddr,
|
||||
const ox::FileAddress &paletteAddr) noexcept {
|
||||
auto &gctx = static_cast<GlContext&>(*ctx);
|
||||
auto &kctx = *gctx.turbineCtx;
|
||||
oxRequire(tilesheet, readObj<CompactTileSheet>(&kctx, tilesheetAddr));
|
||||
@ -465,8 +488,8 @@ void setSprite(Context *ctx,
|
||||
int x,
|
||||
int y,
|
||||
unsigned tileIdx,
|
||||
[[maybe_unused]] unsigned spriteShape,
|
||||
[[maybe_unused]] unsigned spriteSize,
|
||||
unsigned spriteShape,
|
||||
unsigned spriteSize,
|
||||
unsigned flipX) noexcept {
|
||||
//oxTracef("nostalgia::core::gfx::gl", "setSprite(ctx, {}, {}, {}, {}, {}, {}, {})",
|
||||
// idx, x, y, tileIdx, spriteShape, spriteSize, flipX);
|
||||
@ -519,7 +542,12 @@ void setSprite(Context *ctx,
|
||||
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(
|
||||
"nostalgia::core::gfx::setTile",
|
||||
"bgIdx: {}, column: {}, row: {}, tile: {}",
|
||||
@ -546,6 +574,7 @@ void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) no
|
||||
namespace gl {
|
||||
|
||||
void drawMainView(core::Context *ctx, ox::Size const&renderSz) noexcept {
|
||||
glViewport(0, 0, renderSz.width, renderSz.height);
|
||||
// clear screen
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
@ -149,7 +149,7 @@ ox::Error PaletteEditorImGui::saveItem() noexcept {
|
||||
const auto sctx = applicationData<studio::StudioContext>(*m_ctx);
|
||||
oxReturnError(sctx->project->writeObj(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 {
|
||||
setUnsavedChanges(true);
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
void TileSheetEditorImGui::SubSheetEditor::draw() noexcept {
|
||||
|
@ -103,18 +103,26 @@ class DrawCommand: public TileSheetCommand {
|
||||
int m_palIdx = 0;
|
||||
|
||||
public:
|
||||
constexpr DrawCommand(TileSheet *img, const TileSheet::SubSheetIdx &subSheetIdx, std::size_t idx, int palIdx) noexcept {
|
||||
m_img = img;
|
||||
auto &subsheet = m_img->getSubSheet(subSheetIdx);
|
||||
m_subSheetIdx = subSheetIdx;
|
||||
constexpr DrawCommand(
|
||||
TileSheet &img,
|
||||
TileSheet::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_palIdx = palIdx;
|
||||
}
|
||||
|
||||
constexpr DrawCommand(TileSheet *img, const TileSheet::SubSheetIdx &subSheetIdx, const ox::Vector<std::size_t> &idxList, int palIdx) noexcept {
|
||||
m_img = img;
|
||||
auto &subsheet = m_img->getSubSheet(subSheetIdx);
|
||||
m_subSheetIdx = subSheetIdx;
|
||||
constexpr DrawCommand(
|
||||
TileSheet &img,
|
||||
TileSheet::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) {
|
||||
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 {
|
||||
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
|
||||
auto existing = ox::find_if(m_changes.cbegin(), m_changes.cend(), [idx](const auto &c) {
|
||||
return c.idx == idx;
|
||||
@ -184,35 +192,40 @@ class CutPasteCommand: public TileSheetCommand {
|
||||
oldPalIdx = pOldPalIdx;
|
||||
}
|
||||
};
|
||||
TileSheet *m_img = nullptr;
|
||||
TileSheet &m_img;
|
||||
TileSheet::SubSheetIdx m_subSheetIdx;
|
||||
ox::Vector<Change> m_changes;
|
||||
|
||||
public:
|
||||
constexpr CutPasteCommand(TileSheet *img, const TileSheet::SubSheetIdx &subSheetIdx, const ox::Point &dstStart, const ox::Point &dstEnd, const TileSheetClipboard &cb) noexcept {
|
||||
m_img = img;
|
||||
m_subSheetIdx = subSheetIdx;
|
||||
const auto &subsheet = m_img->getSubSheet(subSheetIdx);
|
||||
constexpr CutPasteCommand(
|
||||
TileSheet &img,
|
||||
TileSheet::SubSheetIdx 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()) {
|
||||
const auto dstPt = p.pt + dstStart;
|
||||
if (dstPt.x <= dstEnd.x && dstPt.y <= dstEnd.y) {
|
||||
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 {
|
||||
auto &subsheet = m_img->getSubSheet(m_subSheetIdx);
|
||||
auto &subsheet = m_img.getSubSheet(m_subSheetIdx);
|
||||
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 {
|
||||
auto &subsheet = m_img->getSubSheet(m_subSheetIdx);
|
||||
auto &subsheet = m_img.getSubSheet(m_subSheetIdx);
|
||||
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 {
|
||||
private:
|
||||
TileSheet *m_img = nullptr;
|
||||
TileSheet &m_img;
|
||||
TileSheet::SubSheetIdx m_parentIdx;
|
||||
ox::Vector<TileSheet::SubSheetIdx, 2> m_addedSheets;
|
||||
|
||||
public:
|
||||
constexpr AddSubSheetCommand(TileSheet *img, const TileSheet::SubSheetIdx &parentIdx) noexcept {
|
||||
m_img = img;
|
||||
m_parentIdx = parentIdx;
|
||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
||||
constexpr AddSubSheetCommand(TileSheet &img, TileSheet::SubSheetIdx parentIdx) noexcept:
|
||||
m_img(img),
|
||||
m_parentIdx(std::move(parentIdx)) {
|
||||
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||
if (parent.subsheets.size()) {
|
||||
auto idx = m_parentIdx;
|
||||
idx.emplace_back(parent.subsheets.size());
|
||||
@ -247,26 +260,26 @@ class AddSubSheetCommand: public TileSheetCommand {
|
||||
auto idx = m_parentIdx;
|
||||
idx.emplace_back(0u);
|
||||
m_addedSheets.push_back(idx);
|
||||
idx.back().value = 1;
|
||||
*idx.back().value = 1;
|
||||
m_addedSheets.push_back(idx);
|
||||
}
|
||||
}
|
||||
|
||||
void redo() noexcept final {
|
||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
||||
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||
if (m_addedSheets.size() < 2) {
|
||||
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 {
|
||||
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.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 {
|
||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
||||
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||
if (parent.subsheets.size() == 2) {
|
||||
auto s = parent.subsheets[0];
|
||||
parent.rows = s.rows;
|
||||
@ -275,7 +288,7 @@ class AddSubSheetCommand: public TileSheetCommand {
|
||||
parent.subsheets.clear();
|
||||
} else {
|
||||
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 {
|
||||
private:
|
||||
TileSheet *m_img = nullptr;
|
||||
TileSheet &m_img;
|
||||
TileSheet::SubSheetIdx m_idx;
|
||||
TileSheet::SubSheetIdx m_parentIdx;
|
||||
TileSheet::SubSheet m_sheet;
|
||||
|
||||
public:
|
||||
constexpr RmSubSheetCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx) noexcept {
|
||||
m_img = img;
|
||||
m_idx = idx;
|
||||
constexpr RmSubSheetCommand(TileSheet &img, TileSheet::SubSheetIdx idx) noexcept:
|
||||
m_img(img),
|
||||
m_idx(std::move(idx)) {
|
||||
m_parentIdx = idx;
|
||||
m_parentIdx.pop_back();
|
||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
||||
m_sheet = parent.subsheets[idx.back().value];
|
||||
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||
m_sheet = parent.subsheets[*idx.back().value];
|
||||
}
|
||||
|
||||
void redo() noexcept final {
|
||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
||||
oxLogError(parent.subsheets.erase(m_idx.back().value).error);
|
||||
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||
oxLogError(parent.subsheets.erase(*m_idx.back().value).error);
|
||||
}
|
||||
|
||||
void undo() noexcept final {
|
||||
auto &parent = m_img->getSubSheet(m_parentIdx);
|
||||
auto i = m_idx.back().value;
|
||||
auto &parent = m_img.getSubSheet(m_parentIdx);
|
||||
auto i = *m_idx.back().value;
|
||||
parent.subsheets.insert(i, m_sheet);
|
||||
}
|
||||
|
||||
@ -334,23 +347,27 @@ class RmSubSheetCommand: public TileSheetCommand {
|
||||
|
||||
class InsertTilesCommand: public TileSheetCommand {
|
||||
private:
|
||||
TileSheet *m_img = nullptr;
|
||||
TileSheet &m_img;
|
||||
TileSheet::SubSheetIdx m_idx;
|
||||
std::size_t m_insertPos = 0;
|
||||
std::size_t m_insertCnt = 0;
|
||||
ox::Vector<uint8_t> m_deletedPixels = {};
|
||||
|
||||
public:
|
||||
constexpr InsertTilesCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
||||
const unsigned bytesPerTile = img->bpp == 4 ? PixelsPerTile / 2 : PixelsPerTile;
|
||||
m_img = img;
|
||||
m_idx = idx;
|
||||
constexpr InsertTilesCommand(
|
||||
TileSheet &img,
|
||||
TileSheet::SubSheetIdx 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_insertCnt = tileCnt * bytesPerTile;
|
||||
m_deletedPixels.resize(m_insertCnt);
|
||||
// copy pixels to be erased
|
||||
{
|
||||
auto &s = m_img->getSubSheet(m_idx);
|
||||
auto &s = m_img.getSubSheet(m_idx);
|
||||
auto &p = s.pixels;
|
||||
auto dst = m_deletedPixels.data();
|
||||
auto src = p.data() + p.size() - m_insertCnt;
|
||||
@ -360,7 +377,7 @@ class InsertTilesCommand: public TileSheetCommand {
|
||||
}
|
||||
|
||||
void redo() noexcept final {
|
||||
auto &s = m_img->getSubSheet(m_idx);
|
||||
auto &s = m_img.getSubSheet(m_idx);
|
||||
auto &p = s.pixels;
|
||||
auto dstPos = m_insertPos + m_insertCnt;
|
||||
const auto dst = p.data() + dstPos;
|
||||
@ -370,7 +387,7 @@ class InsertTilesCommand: public TileSheetCommand {
|
||||
}
|
||||
|
||||
void undo() noexcept final {
|
||||
auto &s = m_img->getSubSheet(m_idx);
|
||||
auto &s = m_img.getSubSheet(m_idx);
|
||||
auto &p = s.pixels;
|
||||
const auto srcIdx = m_insertPos + m_insertCnt;
|
||||
const auto src = p.data() + srcIdx;
|
||||
@ -395,23 +412,27 @@ class InsertTilesCommand: public TileSheetCommand {
|
||||
|
||||
class DeleteTilesCommand: public TileSheetCommand {
|
||||
private:
|
||||
TileSheet *m_img = nullptr;
|
||||
TileSheet &m_img;
|
||||
TileSheet::SubSheetIdx m_idx;
|
||||
std::size_t m_deletePos = 0;
|
||||
std::size_t m_deleteSz = 0;
|
||||
ox::Vector<uint8_t> m_deletedPixels = {};
|
||||
|
||||
public:
|
||||
constexpr DeleteTilesCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx, std::size_t tileIdx, std::size_t tileCnt) noexcept {
|
||||
const unsigned bytesPerTile = img->bpp == 4 ? PixelsPerTile / 2 : PixelsPerTile;
|
||||
m_img = img;
|
||||
m_idx = idx;
|
||||
constexpr DeleteTilesCommand(
|
||||
TileSheet &img,
|
||||
TileSheet::SubSheetIdx 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_deleteSz = tileCnt * bytesPerTile;
|
||||
m_deletedPixels.resize(m_deleteSz);
|
||||
// copy pixels to be erased
|
||||
{
|
||||
auto &s = m_img->getSubSheet(m_idx);
|
||||
auto &s = m_img.getSubSheet(m_idx);
|
||||
auto &p = s.pixels;
|
||||
auto dst = m_deletedPixels.data();
|
||||
auto src = p.data() + m_deletePos;
|
||||
@ -421,7 +442,7 @@ class DeleteTilesCommand: public TileSheetCommand {
|
||||
}
|
||||
|
||||
void redo() noexcept final {
|
||||
auto &s = m_img->getSubSheet(m_idx);
|
||||
auto &s = m_img.getSubSheet(m_idx);
|
||||
auto &p = s.pixels;
|
||||
auto srcPos = m_deletePos + m_deleteSz;
|
||||
const auto src = p.data() + srcPos;
|
||||
@ -432,7 +453,7 @@ class DeleteTilesCommand: public TileSheetCommand {
|
||||
}
|
||||
|
||||
void undo() noexcept final {
|
||||
auto &s = m_img->getSubSheet(m_idx);
|
||||
auto &s = m_img.getSubSheet(m_idx);
|
||||
auto &p = s.pixels;
|
||||
const auto src = p.data() + m_deletePos;
|
||||
const auto dst1 = p.data() + m_deletePos + m_deleteSz;
|
||||
@ -456,7 +477,7 @@ class DeleteTilesCommand: public TileSheetCommand {
|
||||
|
||||
class UpdateSubSheetCommand: public TileSheetCommand {
|
||||
private:
|
||||
TileSheet *m_img = nullptr;
|
||||
TileSheet &m_img;
|
||||
TileSheet::SubSheetIdx m_idx;
|
||||
TileSheet::SubSheet m_sheet;
|
||||
ox::String m_newName;
|
||||
@ -464,26 +485,30 @@ class UpdateSubSheetCommand: public TileSheetCommand {
|
||||
int m_newRows = 0;
|
||||
|
||||
public:
|
||||
constexpr UpdateSubSheetCommand(TileSheet *img, const TileSheet::SubSheetIdx &idx,
|
||||
const ox::String &name, int cols, int rows) noexcept {
|
||||
m_img = img;
|
||||
m_idx = idx;
|
||||
m_sheet = img->getSubSheet(idx);
|
||||
constexpr UpdateSubSheetCommand(
|
||||
TileSheet &img,
|
||||
TileSheet::SubSheetIdx idx,
|
||||
const ox::String &name,
|
||||
int cols,
|
||||
int rows) noexcept:
|
||||
m_img(img),
|
||||
m_idx(std::move(idx)) {
|
||||
m_sheet = m_img.getSubSheet(m_idx);
|
||||
m_newName = name;
|
||||
m_newCols = cols;
|
||||
m_newRows = rows;
|
||||
}
|
||||
|
||||
void redo() noexcept final {
|
||||
auto &sheet = m_img->getSubSheet(m_idx);
|
||||
auto &sheet = m_img.getSubSheet(m_idx);
|
||||
sheet.name = m_newName;
|
||||
sheet.columns = m_newCols;
|
||||
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 {
|
||||
auto &sheet = m_img->getSubSheet(m_idx);
|
||||
auto &sheet = m_img.getSubSheet(m_idx);
|
||||
sheet = m_sheet;
|
||||
}
|
||||
|
||||
@ -501,25 +526,28 @@ class UpdateSubSheetCommand: public TileSheetCommand {
|
||||
|
||||
class PaletteChangeCommand: public TileSheetCommand {
|
||||
private:
|
||||
TileSheet &m_img;
|
||||
TileSheet::SubSheetIdx m_idx;
|
||||
TileSheet *m_img = nullptr;
|
||||
ox::FileAddress m_oldPalette;
|
||||
ox::FileAddress m_newPalette;
|
||||
|
||||
public:
|
||||
PaletteChangeCommand(const TileSheet::SubSheetIdx &idx, TileSheet *img, ox::CRStringView newPalette) noexcept {
|
||||
m_idx = idx;
|
||||
m_img = img;
|
||||
m_oldPalette = m_img->defaultPalette;
|
||||
PaletteChangeCommand(
|
||||
TileSheet::SubSheetIdx idx,
|
||||
TileSheet &img,
|
||||
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));
|
||||
}
|
||||
|
||||
void redo() noexcept final {
|
||||
m_img->defaultPalette = m_newPalette;
|
||||
m_img.defaultPalette = m_newPalette;
|
||||
}
|
||||
|
||||
void undo() noexcept final {
|
||||
m_img->defaultPalette = m_oldPalette;
|
||||
m_img.defaultPalette = m_oldPalette;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -535,9 +563,9 @@ class PaletteChangeCommand: public TileSheetCommand {
|
||||
};
|
||||
|
||||
|
||||
TileSheetEditorModel::TileSheetEditorModel(turbine::Context *ctx, ox::String path) {
|
||||
m_ctx = ctx;
|
||||
m_path = std::move(path);
|
||||
TileSheetEditorModel::TileSheetEditorModel(turbine::Context *ctx, ox::String path):
|
||||
m_ctx(ctx),
|
||||
m_path(std::move(path)) {
|
||||
oxRequireT(img, readObj<TileSheet>(ctx, m_path));
|
||||
m_img = *img;
|
||||
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 pt2 = ox::Point(s->columns * TileWidth, s->rows * TileHeight);
|
||||
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() {
|
||||
@ -594,7 +622,7 @@ void TileSheetEditorModel::paste() {
|
||||
const auto s = activeSubSheet();
|
||||
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);
|
||||
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 {
|
||||
@ -617,8 +645,8 @@ ox::StringView TileSheetEditorModel::palPath() const noexcept {
|
||||
|
||||
ox::Error TileSheetEditorModel::setPalette(const ox::String &path) noexcept {
|
||||
oxRequire(uuid, m_ctx->pathToUuid.at(path));
|
||||
pushCommand(ox::make<PaletteChangeCommand>(activeSubSheetIdx(), &m_img, uuid->toString()));
|
||||
return OxError(0);
|
||||
pushCommand(ox::make<PaletteChangeCommand>(activeSubSheetIdx(), m_img, uuid->toString()));
|
||||
return {};
|
||||
}
|
||||
|
||||
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) {
|
||||
m_updated = m_updated || m_ongoingDrawCommand->append(idx);
|
||||
} 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 {
|
||||
pushCommand(ox::make<AddSubSheetCommand>(&m_img, parentIdx));
|
||||
pushCommand(ox::make<AddSubSheetCommand>(m_img, parentIdx));
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
pushCommand(ox::make<UpdateSubSheetCommand>(&m_img, idx, name, cols, rows));
|
||||
return OxError(0);
|
||||
pushCommand(ox::make<UpdateSubSheetCommand>(m_img, idx, name, cols, rows));
|
||||
return {};
|
||||
}
|
||||
|
||||
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) {
|
||||
m_updated = m_updated || m_ongoingDrawCommand->append(idxList);
|
||||
} 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) {
|
||||
setActiveSubsheet(idx);
|
||||
}
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
ox::Error TileSheetEditorModel::markUpdated() noexcept {
|
||||
m_updated = true;
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
void TileSheetEditorModel::ackUpdate() noexcept {
|
||||
|
@ -97,7 +97,7 @@ bool TileSheetEditorView::updated() const noexcept {
|
||||
|
||||
ox::Error TileSheetEditorView::markUpdated() noexcept {
|
||||
m_updated = true;
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
void TileSheetEditorView::ackUpdate() noexcept {
|
||||
|
@ -387,7 +387,7 @@ struct TileSheet {
|
||||
if (pSubsheet->subsheets.size() <= currentIdx) {
|
||||
auto out = pIdx;
|
||||
if (!pSubsheet->subsheets.empty()) {
|
||||
out.back().value = pSubsheet->subsheets.size() - 1;
|
||||
*out.back().value = pSubsheet->subsheets.size() - 1;
|
||||
} else {
|
||||
out.pop_back();
|
||||
}
|
||||
|
@ -349,7 +349,7 @@ ox::Error StudioUI::openFileActiveTab(ox::CRStringView path, bool makeActiveTab)
|
||||
m_editors.emplace_back(editor);
|
||||
m_openFiles.emplace_back(path);
|
||||
if (makeActiveTab) {
|
||||
m_activeEditor = m_editors.back().value.get();
|
||||
m_activeEditor = m_editors.back().value->get();
|
||||
m_activeEditorUpdatePending = editor;
|
||||
}
|
||||
// save to config
|
||||
|
@ -49,7 +49,7 @@ ox::Error writeConfig(keel::Context *ctx, ox::CRStringView name, T *data) noexce
|
||||
return err;
|
||||
}
|
||||
oxRequireM(buff, ox::writeOC(*data));
|
||||
buff.back().value = '\n';
|
||||
*buff.back().value = '\n';
|
||||
if (const auto err = fs.write(path, buff.data(), buff.size())) {
|
||||
oxErrf("Could not read config file: {}\n", toStr(err));
|
||||
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()) {
|
||||
oxRequireM(typeOut, ox::writeClaw(*t, ox::ClawFormat::Organic));
|
||||
// replace garbage last character with new line
|
||||
typeOut.back().value = '\n';
|
||||
*typeOut.back().value = '\n';
|
||||
// write to FS
|
||||
const auto typePath = ox::sfmt("/{}/{}", descPath, buildTypeId(*t));
|
||||
oxReturnError(writeBuff(typePath, typeOut));
|
||||
|
@ -17,7 +17,7 @@ void UndoStack::push(UndoCommand *cmd) noexcept {
|
||||
cmd->redo();
|
||||
redoTriggered.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_stackIdx;
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user