[nostalgia,studio] Update for Ox changes, cleanup

This commit is contained in:
Gary Talent 2023-06-13 23:52:27 -05:00
parent dde51151ff
commit ba50b083ff
10 changed files with 195 additions and 138 deletions

View File

@ -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);

View File

@ -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 {};
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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();
}

View File

@ -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

View File

@ -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");

View 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));

View File

@ -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 {