Compare commits

..

1 Commits

Author SHA1 Message Date
889fe04255 [nostalgia/studio] Set version to 2024.05.0
All checks were successful
Build / build (push) Successful in 2m29s
2024-05-23 22:11:52 -05:00
53 changed files with 213 additions and 365 deletions

View File

@ -13,7 +13,6 @@
#include <ox/std/error.hpp> #include <ox/std/error.hpp>
#include <ox/std/size.hpp> #include <ox/std/size.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/vec.hpp>
#include <ox/std/vector.hpp> #include <ox/std/vector.hpp>
namespace glutils { namespace glutils {
@ -138,22 +137,6 @@ struct FrameBuffer {
constexpr operator const GLuint&() const noexcept { constexpr operator const GLuint&() const noexcept {
return fbo.id; return fbo.id;
} }
[[nodiscard]]
constexpr ox::Vec2 sizef() const noexcept {
return {
static_cast<float>(width),
static_cast<float>(height),
};
}
[[nodiscard]]
constexpr ox::Size size() const noexcept {
return {
width,
height,
};
}
}; };
class FrameBufferBind { class FrameBufferBind {

View File

@ -102,7 +102,7 @@ void setupShaderParams(
ox::Vector<ShaderVarSet> const&vars, ox::Vector<ShaderVarSet> const&vars,
GLsizei vertexRowLen) noexcept { GLsizei vertexRowLen) noexcept {
// setup vars // setup vars
for (size_t lenWritten = 0; auto const&v : vars) { for (auto lenWritten = 0LU; auto const&v : vars) {
auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str())); auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str()));
glEnableVertexAttribArray(attr); glEnableVertexAttribArray(attr);
glVertexAttribPointer( glVertexAttribPointer(

View File

@ -34,8 +34,7 @@ constexpr auto buildTypeId() noexcept {
return ox::sfmt("{};{}", name, version); return ox::sfmt("{};{}", name, version);
} }
static constexpr auto buildTypeId( static constexpr auto buildTypeId(CRStringView name, int version,
CRStringView name, int version,
const TypeParamPack &typeParams = {}) noexcept { const TypeParamPack &typeParams = {}) noexcept {
String tp; String tp;
if (!typeParams.empty()) { if (!typeParams.empty()) {
@ -43,7 +42,7 @@ static constexpr auto buildTypeId(
for (const auto &p : typeParams) { for (const auto &p : typeParams) {
tp += p + ","; tp += p + ",";
} }
tp.resize(tp.len()); tp.resize(tp.len() - 1);
tp += "#"; tp += "#";
} }
return ox::sfmt("{}{};{}", name, tp, version); return ox::sfmt("{}{};{}", name, tp, version);

View File

@ -8,7 +8,6 @@
#pragma once #pragma once
#include "bit.hpp"
#include "typetraits.hpp" #include "typetraits.hpp"
namespace ox { namespace ox {
@ -30,6 +29,4 @@ concept OxString_c = isOxString_v<T>;
template<typename T> template<typename T>
concept Integral_c = ox::is_integral_v<T>; concept Integral_c = ox::is_integral_v<T>;
template<typename T, size_t max>
concept IntegerRange_c = ox::is_integer_v<T> && ox::MaxValue<T> >= max;
} }

View File

@ -128,10 +128,6 @@ struct SpanIterator {
return operator-=(1); return operator-=(1);
} }
constexpr PtrType operator->() const noexcept {
return &m_t[m_offset];
}
constexpr RefType operator*() const noexcept { constexpr RefType operator*() const noexcept {
return m_t[m_offset]; return m_t[m_offset];
} }

View File

@ -102,7 +102,6 @@ class MallocaPtr {
} }
constexpr ~MallocaPtr() noexcept { constexpr ~MallocaPtr() noexcept {
m_val->~T();
if (m_onHeap && m_val) { if (m_onHeap && m_val) {
delete[] reinterpret_cast<uint8_t*>(m_val); delete[] reinterpret_cast<uint8_t*>(m_val);
} }

View File

@ -17,8 +17,8 @@ class Point {
public: public:
static constexpr auto TypeName = "net.drinkingtea.ox.Point"; static constexpr auto TypeName = "net.drinkingtea.ox.Point";
static constexpr auto TypeVersion = 1; static constexpr auto TypeVersion = 1;
int32_t x = 0; int x = 0;
int32_t y = 0; int y = 0;
constexpr Point() noexcept = default; constexpr Point() noexcept = default;

View File

@ -8,7 +8,7 @@
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
#include <istream> #include <cstdio>
#include "array.hpp" #include "array.hpp"
#include "reader.hpp" #include "reader.hpp"
@ -16,56 +16,41 @@
namespace ox { namespace ox {
[[nodiscard]] [[nodiscard]]
constexpr std::ios_base::seekdir sdMap(ox::ios_base::seekdir in) noexcept { constexpr int sdMap(ox::ios_base::seekdir in) noexcept {
switch (in) { switch (in) {
case ox::ios_base::beg: case ox::ios_base::beg:
return std::ios_base::beg; return SEEK_SET;
case ox::ios_base::end: case ox::ios_base::end:
return std::ios_base::end; return SEEK_END;
case ox::ios_base::cur: case ox::ios_base::cur:
return std::ios_base::cur; return SEEK_CUR;
} }
return std::ios_base::beg; return -1;
} }
ox::Result<char> StreamReader::peek() const noexcept { ox::Result<char> FileReader::peek() const noexcept {
try { auto const c = fgetc(m_file);
char c{};
m_strm.get(c);
auto const ok = c != EOF; auto const ok = c != EOF;
if (ok && m_strm.unget()) [[unlikely]] { if (ok && ungetc(c, m_file)) [[unlikely]] {
return OxError(1, "Unable to unget character"); return OxError(1, "Unable to unget character");
} }
return {static_cast<char>(c), OxError(!ok, "File peek failed")}; return {static_cast<char>(c), OxError(!ok, "File peek failed")};
} catch (std::exception const&) {
return OxError(1, "peek failed");
}
} }
ox::Result<std::size_t> StreamReader::read(char *v, std::size_t cnt) noexcept { ox::Result<std::size_t> FileReader::read(char *v, std::size_t cnt) noexcept {
return static_cast<size_t>(m_strm.read(v, static_cast<std::streamsize>(cnt)).gcount()); return fread(v, 1, cnt, m_file);
} }
ox::Error StreamReader::seekg(std::size_t p) noexcept { ox::Error FileReader::seekg(std::size_t p) noexcept {
try { return OxError(fseek(m_file, static_cast<int64_t>(p), SEEK_CUR) != 0);
m_strm.seekg(static_cast<long long int>(p), std::ios_base::cur);
} catch (std::exception const&) {
return OxError(1, "seekg failed");
}
return {};
} }
ox::Error StreamReader::seekg(int64_t p, ios_base::seekdir sd) noexcept { ox::Error FileReader::seekg(int64_t p, ios_base::seekdir sd) noexcept {
try { return OxError(fseek(m_file, p, sdMap(sd)) != 0);
m_strm.seekg(p, sdMap(sd));
} catch (std::exception const&) {
return OxError(1, "seekg failed");
}
return {};
} }
ox::Result<std::size_t> StreamReader::tellg() noexcept { ox::Result<std::size_t> FileReader::tellg() noexcept {
const auto sz = m_strm.tellg(); const auto sz = ftell(m_file);
return {static_cast<std::size_t>(sz), OxError(sz == -1)}; return {static_cast<std::size_t>(sz), OxError(sz == -1)};
} }

View File

@ -9,7 +9,7 @@
#pragma once #pragma once
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
#include <istream> #include <cstdio>
#endif #endif
#include "concepts.hpp" #include "concepts.hpp"
@ -65,11 +65,11 @@ class ReaderT: public Reader_v {
}; };
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
class StreamReader: public Reader_v { class FileReader: public Reader_v {
private: private:
std::istream &m_strm; FILE *m_file = nullptr;
public: public:
constexpr explicit StreamReader(std::istream &stream) noexcept: m_strm(stream) {} constexpr explicit FileReader(FILE *file) noexcept: m_file(file) {}
ox::Result<char> peek() const noexcept override; ox::Result<char> peek() const noexcept override;
ox::Result<std::size_t> read(char *v, std::size_t cnt) noexcept override; ox::Result<std::size_t> read(char *v, std::size_t cnt) noexcept override;
ox::Error seekg(std::size_t p) noexcept override; ox::Error seekg(std::size_t p) noexcept override;

View File

@ -17,8 +17,8 @@ class Size {
public: public:
static constexpr auto TypeName = "net.drinkingtea.ox.Size"; static constexpr auto TypeName = "net.drinkingtea.ox.Size";
static constexpr auto TypeVersion = 1; static constexpr auto TypeVersion = 1;
int32_t width = 0; int width = 0;
int32_t height = 0; int height = 0;
constexpr Size() noexcept = default; constexpr Size() noexcept = default;

View File

@ -8,7 +8,7 @@
#pragma once #pragma once
#include "def.hpp" #include "algorithm.hpp"
#include "hash.hpp" #include "hash.hpp"
#include "ignore.hpp" #include "ignore.hpp"
#include "stringview.hpp" #include "stringview.hpp"
@ -28,7 +28,7 @@ class SmallMap {
T value{}; T value{};
}; };
protected: private:
using PairVector = Vector<Pair, SmallSz>; using PairVector = Vector<Pair, SmallSz>;
PairVector m_pairs; PairVector m_pairs;
@ -79,11 +79,6 @@ class SmallMap {
[[nodiscard]] [[nodiscard]]
constexpr Pair &get(size_t i) noexcept; constexpr Pair &get(size_t i) noexcept;
[[nodiscard]]
constexpr ox::SpanView<Pair> pairs() const noexcept {
return m_pairs;
}
constexpr void clear(); constexpr void clear();
private: private:
@ -209,12 +204,12 @@ constexpr T &SmallMap<K, T, SmallSz>::value(size_t i) noexcept {
} }
template<typename K, typename T, size_t SmallSz> template<typename K, typename T, size_t SmallSz>
constexpr typename SmallMap<K, T, SmallSz>::Pair const&SmallMap<K, T, SmallSz>::get(size_t i) const noexcept { constexpr SmallMap<K, T, SmallSz>::Pair const&SmallMap<K, T, SmallSz>::get(size_t i) const noexcept {
return m_pairs[i]; return m_pairs[i];
} }
template<typename K, typename T, size_t SmallSz> template<typename K, typename T, size_t SmallSz>
constexpr typename SmallMap<K, T, SmallSz>::Pair &SmallMap<K, T, SmallSz>::get(size_t i) noexcept { constexpr SmallMap<K, T, SmallSz>::Pair &SmallMap<K, T, SmallSz>::get(size_t i) noexcept {
return m_pairs[i]; return m_pairs[i];
} }
@ -251,12 +246,4 @@ constexpr typename SmallMap<K, T, SmallSz>::Pair &SmallMap<K, T, SmallSz>::acces
return pairs.emplace_back(); return pairs.emplace_back();
} }
template<typename T, typename K, typename V, size_t SmallSz>
constexpr Error model(T *io, ox::CommonPtrWith<SmallMap<K, V, SmallSz>> auto *obj) noexcept {
using Map = SmallMap<K, V, SmallSz>;
oxReturnError(io->template setTypeInfo<Map>());
oxReturnError(io->field("pairs", &obj->m_pairs));
return {};
}
} }

View File

@ -26,7 +26,7 @@
namespace ox { namespace ox {
#if defined(OX_USE_STDLIB) && __has_include(<unistd.h>) #if defined(OX_USE_STDLIB) && __has_include(<unistd.h>)
[[nodiscard]] [[maybe_unused]] [[nodiscard]]
static auto symbolicate([[maybe_unused]]void **frames, static auto symbolicate([[maybe_unused]]void **frames,
[[maybe_unused]]std::size_t frameCnt, [[maybe_unused]]std::size_t frameCnt,
[[maybe_unused]]const char *linePrefix) { [[maybe_unused]]const char *linePrefix) {

View File

@ -194,7 +194,6 @@ class BasicString {
constexpr void resize(size_t sz) noexcept { constexpr void resize(size_t sz) noexcept {
m_buff.resize(sz); m_buff.resize(sz);
m_buff[sz - 1] = 0;
} }
[[nodiscard]] [[nodiscard]]

View File

@ -271,7 +271,7 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
constexpr bool contains(MaybeView_t<T> const&) const noexcept; constexpr bool contains(MaybeView_t<T> const&) const noexcept;
constexpr iterator<T&, T*, false> insert( constexpr iterator<T&, T*, false> insert(
std::size_t pos, std::size_t cnt, T const&val) noexcept(useNoexcept); std::size_t pos, std::size_t cnt, T val) noexcept(useNoexcept);
constexpr iterator<T&, T*, false> insert(std::size_t pos, T val) noexcept(useNoexcept); constexpr iterator<T&, T*, false> insert(std::size_t pos, T val) noexcept(useNoexcept);
@ -531,23 +531,29 @@ constexpr bool Vector<T, SmallVectorSize, Allocator>::contains(MaybeView_t<T> co
template<typename T, std::size_t SmallVectorSize, typename Allocator> template<typename T, std::size_t SmallVectorSize, typename Allocator>
constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false> constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&, T*, false>
Vector<T, SmallVectorSize, Allocator>::insert( Vector<T, SmallVectorSize, Allocator>::insert(
std::size_t pos, std::size_t cnt, T const&val) noexcept(useNoexcept) { std::size_t pos, std::size_t cnt, T val) noexcept(useNoexcept) {
if (m_size + cnt > m_cap) { if (m_size + cnt > m_cap) {
reserveInsert(m_cap ? m_size + cnt : initialCap, pos, cnt); reserveInsert(m_cap ? m_size + cnt : initialCap, pos, cnt);
}
if (pos < m_size) { if (pos < m_size) {
for (auto i = m_size + cnt - 1; i > pos; --i) { m_items[pos] = std::move(val);
std::construct_at(&m_items[i], std::move(m_items[i - cnt]));
}
for (auto i = pos; i < pos + cnt; ++i) {
m_items[i] = val;
}
} else { } else {
for (auto i = 0u; i < cnt; ++i) { for (auto i = 0u; i < cnt; ++i) {
std::construct_at(&m_items[pos + i], m_items[pos]); std::construct_at(&m_items[pos + i], m_items[pos]);
} }
} }
m_size += cnt; } else {
if (pos < m_size) {
for (auto i = m_size + cnt - 1; i > pos; --i) {
std::construct_at(&m_items[i], std::move(m_items[i - cnt]));
}
m_items[pos] = std::move(val);
} else {
for (auto i = 0u; i < cnt; ++i) {
std::construct_at(&m_items[pos + i], m_items[pos]);
}
}
}
++m_size;
return begin() + pos; return begin() + pos;
} }
@ -556,14 +562,20 @@ constexpr typename Vector<T, SmallVectorSize, Allocator>::template iterator<T&,
Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, T val) noexcept(useNoexcept) { Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, T val) noexcept(useNoexcept) {
if (m_size == m_cap) { if (m_size == m_cap) {
reserveInsert(m_cap ? m_cap * 2 : initialCap, pos); reserveInsert(m_cap ? m_cap * 2 : initialCap, pos);
if (pos < m_size) {
m_items[pos] = std::move(val);
} else {
std::construct_at(&m_items[pos], m_items[pos]);
} }
} else {
if (pos < m_size) { if (pos < m_size) {
for (auto i = m_size; i > pos; --i) { for (auto i = m_size; i > pos; --i) {
std::construct_at(&m_items[i], std::move(m_items[i - 1])); std::construct_at(&m_items[i], std::move(m_items[i - 1]));
} }
m_items[pos] = std::move(val); m_items[pos] = std::move(val);
} else { } else {
std::construct_at(&m_items[pos], std::move(val)); std::construct_at(&m_items[pos], m_items[pos]);
}
} }
++m_size; ++m_size;
return begin() + pos; return begin() + pos;

View File

@ -103,12 +103,6 @@ oxModelEnd()
void addEntry(TileSheetSet &set, ox::FileAddress path, int32_t begin = 0, int32_t size = -1) noexcept; void addEntry(TileSheetSet &set, ox::FileAddress path, int32_t begin = 0, int32_t size = -1) noexcept;
[[nodiscard]]
int tileColumns(Context&) noexcept;
[[nodiscard]]
int tileRows(Context&) noexcept;
ox::Error loadBgPalette( ox::Error loadBgPalette(
Context &ctx, Context &ctx,
size_t palBank, size_t palBank,

View File

@ -222,14 +222,6 @@ ox::Error setPixelCount(TileSheet::SubSheet &ss, int8_t pBpp, std::size_t cnt) n
[[nodiscard]] [[nodiscard]]
unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept; unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept;
/**
*
* @param ss
* @param pBpp
* @param sz size of Subsheet in tiles (not pixels)
*/
ox::Error resizeSubsheet(TileSheet::SubSheet &ss, int8_t pBpp, ox::Size const&sz) noexcept;
/** /**
* validateSubSheetIdx takes a SubSheetIdx and moves the index to the * validateSubSheetIdx takes a SubSheetIdx and moves the index to the
* preceding or parent sheet if the current corresponding sheet does * preceding or parent sheet if the current corresponding sheet does

View File

@ -22,6 +22,8 @@
namespace nostalgia::core { namespace nostalgia::core {
constexpr auto GbaTileColumns = 32;
constexpr auto GbaTileRows = 32;
constexpr auto SpriteCount = 128; constexpr auto SpriteCount = 128;
struct GbaTileMapTarget { struct GbaTileMapTarget {
@ -282,8 +284,8 @@ ox::Error loadSpriteTileSheet(
return {}; return {};
} }
void setBgTile(Context &ctx, uint_t bgIdx, int column, int row, BgTile const&tile) noexcept { void setBgTile(Context&, uint_t bgIdx, int column, int row, BgTile const&tile) noexcept {
auto const tileIdx = static_cast<std::size_t>(row * tileColumns(ctx) + column); auto const tileIdx = static_cast<std::size_t>(row * GbaTileColumns + column);
// see Tonc 9.3 // see Tonc 9.3
MEM_BG_MAP[bgIdx][tileIdx] = MEM_BG_MAP[bgIdx][tileIdx] =
static_cast<uint16_t>(tile.tileIdx & 0b1'1111'1111) | static_cast<uint16_t>(tile.tileIdx & 0b1'1111'1111) |
@ -292,8 +294,8 @@ void setBgTile(Context &ctx, uint_t bgIdx, int column, int row, BgTile const&til
static_cast<uint16_t>(tile.palBank << 0xc); static_cast<uint16_t>(tile.palBank << 0xc);
} }
void clearBg(Context &ctx, uint_t bgIdx) noexcept { void clearBg(Context&, uint_t bgIdx) noexcept {
memset(MEM_BG_MAP[bgIdx].data(), 0, static_cast<size_t>(tileRows(ctx) * tileColumns(ctx))); memset(MEM_BG_MAP[bgIdx].data(), 0, GbaTileRows * GbaTileColumns);
} }
uint8_t bgStatus(Context&) noexcept { uint8_t bgStatus(Context&) noexcept {

View File

@ -6,17 +6,6 @@
namespace nostalgia::core { namespace nostalgia::core {
constexpr auto GbaTileColumns = 32;
constexpr auto GbaTileRows = 32;
int tileColumns(Context&) noexcept {
return GbaTileColumns;
}
int tileRows(Context&) noexcept {
return GbaTileRows;
}
// map ASCII values to the nostalgia charset // map ASCII values to the nostalgia charset
constexpr ox::Array<char, 128> charMap = { constexpr ox::Array<char, 128> charMap = {
0, 0,

View File

@ -79,13 +79,13 @@ void PaletteEditorImGui::drawColorsEditor() noexcept {
if (ImGui::Button("Add", sz)) { if (ImGui::Button("Add", sz)) {
auto const colorSz = static_cast<int>(colors(m_pal, m_page)); auto const colorSz = static_cast<int>(colors(m_pal, m_page));
constexpr Color16 c = 0; constexpr Color16 c = 0;
std::ignore = undoStack()->push(ox::make_unique<AddColorCommand>(&m_pal, c, m_page, colorSz)); undoStack()->push(ox::make_unique<AddColorCommand>(&m_pal, c, m_page, colorSz));
} }
ImGui::SameLine(); ImGui::SameLine();
ImGui::BeginDisabled(m_selectedColorRow >= colors(m_pal, m_page)); ImGui::BeginDisabled(m_selectedColorRow >= colors(m_pal, m_page));
{ {
if (ImGui::Button("Remove", sz)) { if (ImGui::Button("Remove", sz)) {
std::ignore = undoStack()->push( undoStack()->push(
ox::make_unique<RemoveColorCommand>( ox::make_unique<RemoveColorCommand>(
&m_pal, &m_pal,
color(m_pal, m_page, static_cast<std::size_t>(m_selectedColorRow)), color(m_pal, m_page, static_cast<std::size_t>(m_selectedColorRow)),
@ -97,7 +97,7 @@ void PaletteEditorImGui::drawColorsEditor() noexcept {
ImGui::BeginDisabled(m_selectedColorRow <= 0); ImGui::BeginDisabled(m_selectedColorRow <= 0);
{ {
if (ImGui::Button("Move Up", sz)) { if (ImGui::Button("Move Up", sz)) {
std::ignore = undoStack()->push(ox::make_unique<MoveColorCommand>(&m_pal, m_page, m_selectedColorRow, -1)); undoStack()->push(ox::make_unique<MoveColorCommand>(&m_pal, m_page, m_selectedColorRow, -1));
--m_selectedColorRow; --m_selectedColorRow;
} }
} }
@ -106,7 +106,7 @@ void PaletteEditorImGui::drawColorsEditor() noexcept {
ImGui::BeginDisabled(m_selectedColorRow >= colors(m_pal, m_page) - 1); ImGui::BeginDisabled(m_selectedColorRow >= colors(m_pal, m_page) - 1);
{ {
if (ImGui::Button("Move Down", sz)) { if (ImGui::Button("Move Down", sz)) {
std::ignore = undoStack()->push(ox::make_unique<MoveColorCommand>(&m_pal, m_page, m_selectedColorRow, 1)); undoStack()->push(ox::make_unique<MoveColorCommand>(&m_pal, m_page, m_selectedColorRow, 1));
++m_selectedColorRow; ++m_selectedColorRow;
} }
} }
@ -155,17 +155,17 @@ void PaletteEditorImGui::drawPagesEditor() noexcept {
constexpr auto toolbarHeight = 40; constexpr auto toolbarHeight = 40;
auto const btnSz = ImVec2(paneSz.x / 3 - 5.5f, 24); auto const btnSz = ImVec2(paneSz.x / 3 - 5.5f, 24);
if (ImGui::Button("Add", btnSz)) { if (ImGui::Button("Add", btnSz)) {
std::ignore = undoStack()->push(ox::make_unique<AddPageCommand>(m_pal)); undoStack()->push(ox::make_unique<AddPageCommand>(m_pal));
m_page = m_pal.pages.size() - 1; m_page = m_pal.pages.size() - 1;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Remove", btnSz)) { if (ImGui::Button("Remove", btnSz)) {
std::ignore = undoStack()->push(ox::make_unique<RemovePageCommand>(m_pal, m_page)); undoStack()->push(ox::make_unique<RemovePageCommand>(m_pal, m_page));
m_page = std::min(m_page, m_pal.pages.size() - 1); m_page = std::min(m_page, m_pal.pages.size() - 1);
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Duplicate", btnSz)) { if (ImGui::Button("Duplicate", btnSz)) {
std::ignore = undoStack()->push(ox::make_unique<DuplicatePageCommand>(m_pal, m_page, m_pal.pages.size())); undoStack()->push(ox::make_unique<DuplicatePageCommand>(m_pal, m_page, m_pal.pages.size()));
} }
ImGui::BeginTable("PageSelect", 2, tableFlags, ImVec2(paneSz.x, paneSz.y - (toolbarHeight + 5))); ImGui::BeginTable("PageSelect", 2, tableFlags, ImVec2(paneSz.x, paneSz.y - (toolbarHeight + 5)));
{ {
@ -198,7 +198,7 @@ void PaletteEditorImGui::drawColorEditor() noexcept {
ImGui::InputInt("Blue", &b, 1, 5); ImGui::InputInt("Blue", &b, 1, 5);
auto const newColor = color16(r, g, b, a); auto const newColor = color16(r, g, b, a);
if (c != newColor) { if (c != newColor) {
std::ignore = undoStack()->push(ox::make_unique<UpdateColorCommand>( undoStack()->push(ox::make_unique<UpdateColorCommand>(
&m_pal, m_page, static_cast<int>(m_selectedColorRow), c, newColor)); &m_pal, m_page, static_cast<int>(m_selectedColorRow), c, newColor));
} }
} }

View File

@ -14,13 +14,12 @@ int AddPageCommand::commandId() const noexcept {
return static_cast<int>(PaletteEditorCommandId::AddPage); return static_cast<int>(PaletteEditorCommandId::AddPage);
} }
ox::Error AddPageCommand::redo() noexcept { void AddPageCommand::redo() noexcept {
m_pal.pages.emplace_back(); m_pal.pages.emplace_back();
return {};
} }
ox::Error AddPageCommand::undo() noexcept { void AddPageCommand::undo() noexcept {
return m_pal.pages.erase(static_cast<std::size_t>(m_pal.pages.size() - 1)).error; std::ignore = m_pal.pages.erase(static_cast<std::size_t>(m_pal.pages.size() - 1));
} }
@ -38,14 +37,13 @@ int DuplicatePageCommand::commandId() const noexcept {
return static_cast<int>(PaletteEditorCommandId::DuplicatePage); return static_cast<int>(PaletteEditorCommandId::DuplicatePage);
} }
ox::Error DuplicatePageCommand::redo() noexcept { void DuplicatePageCommand::redo() noexcept {
m_pal.pages.emplace(m_dstIdx, std::move(m_page)); m_pal.pages.emplace(m_dstIdx, std::move(m_page));
return {};
} }
ox::Error DuplicatePageCommand::undo() noexcept { void DuplicatePageCommand::undo() noexcept {
m_page = std::move(m_pal.pages[m_dstIdx]); m_page = std::move(m_pal.pages[m_dstIdx]);
return m_pal.pages.erase(static_cast<std::size_t>(m_dstIdx)).error; std::ignore = m_pal.pages.erase(static_cast<std::size_t>(m_dstIdx));
} }
size_t DuplicatePageCommand::insertIdx() const noexcept { size_t DuplicatePageCommand::insertIdx() const noexcept {
@ -62,14 +60,13 @@ int RemovePageCommand::commandId() const noexcept {
return static_cast<int>(PaletteEditorCommandId::RemovePage); return static_cast<int>(PaletteEditorCommandId::RemovePage);
} }
ox::Error RemovePageCommand::redo() noexcept { void RemovePageCommand::redo() noexcept {
m_page = std::move(m_pal.pages[m_idx]); m_page = std::move(m_pal.pages[m_idx]);
return m_pal.pages.erase(static_cast<std::size_t>(m_idx)).error; std::ignore = m_pal.pages.erase(static_cast<std::size_t>(m_idx));
} }
ox::Error RemovePageCommand::undo() noexcept { void RemovePageCommand::undo() noexcept {
m_pal.pages.insert(m_idx, std::move(m_page)); m_pal.pages.insert(m_idx, std::move(m_page));
return {};
} }
@ -84,13 +81,12 @@ int AddColorCommand::commandId() const noexcept {
return static_cast<int>(PaletteEditorCommandId::AddColor); return static_cast<int>(PaletteEditorCommandId::AddColor);
} }
ox::Error AddColorCommand::redo() noexcept { void AddColorCommand::redo() noexcept {
m_pal->pages[m_page].insert(static_cast<std::size_t>(m_idx), m_color); m_pal->pages[m_page].insert(static_cast<std::size_t>(m_idx), m_color);
return {};
} }
ox::Error AddColorCommand::undo() noexcept { void AddColorCommand::undo() noexcept {
return m_pal->pages[m_page].erase(static_cast<std::size_t>(m_idx)).error; std::ignore = m_pal->pages[m_page].erase(static_cast<std::size_t>(m_idx));
} }
@ -105,13 +101,12 @@ int RemoveColorCommand::commandId() const noexcept {
return static_cast<int>(PaletteEditorCommandId::RemoveColor); return static_cast<int>(PaletteEditorCommandId::RemoveColor);
} }
ox::Error RemoveColorCommand::redo() noexcept { void RemoveColorCommand::redo() noexcept {
return m_pal->pages[m_page].erase(static_cast<std::size_t>(m_idx)).error; std::ignore = m_pal->pages[m_page].erase(static_cast<std::size_t>(m_idx));
} }
ox::Error RemoveColorCommand::undo() noexcept { void RemoveColorCommand::undo() noexcept {
m_pal->pages[m_page].insert(static_cast<std::size_t>(m_idx), m_color); m_pal->pages[m_page].insert(static_cast<std::size_t>(m_idx), m_color);
return {};
} }
@ -129,11 +124,11 @@ UpdateColorCommand::UpdateColorCommand(
//setObsolete(m_oldColor == m_newColor); //setObsolete(m_oldColor == m_newColor);
} }
bool UpdateColorCommand::mergeWith(UndoCommand const&cmd) noexcept { bool UpdateColorCommand::mergeWith(const UndoCommand *cmd) noexcept {
if (cmd.commandId() != static_cast<int>(PaletteEditorCommandId::UpdateColor)) { if (cmd->commandId() != static_cast<int>(PaletteEditorCommandId::UpdateColor)) {
return false; return false;
} }
auto ucCmd = static_cast<UpdateColorCommand const*>(&cmd); auto ucCmd = static_cast<const UpdateColorCommand*>(cmd);
if (m_idx != ucCmd->m_idx) { if (m_idx != ucCmd->m_idx) {
return false; return false;
} }
@ -146,14 +141,12 @@ int UpdateColorCommand::commandId() const noexcept {
return static_cast<int>(PaletteEditorCommandId::UpdateColor); return static_cast<int>(PaletteEditorCommandId::UpdateColor);
} }
ox::Error UpdateColorCommand::redo() noexcept { void UpdateColorCommand::redo() noexcept {
m_pal->pages[m_page][static_cast<std::size_t>(m_idx)] = m_newColor; m_pal->pages[m_page][static_cast<std::size_t>(m_idx)] = m_newColor;
return {};
} }
ox::Error UpdateColorCommand::undo() noexcept { void UpdateColorCommand::undo() noexcept {
m_pal->pages[m_page][static_cast<std::size_t>(m_idx)] = m_oldColor; m_pal->pages[m_page][static_cast<std::size_t>(m_idx)] = m_oldColor;
return {};
} }
@ -168,14 +161,12 @@ int MoveColorCommand::commandId() const noexcept {
return static_cast<int>(PaletteEditorCommandId::MoveColor); return static_cast<int>(PaletteEditorCommandId::MoveColor);
} }
ox::Error MoveColorCommand::redo() noexcept { void MoveColorCommand::redo() noexcept {
moveColor(static_cast<int>(m_idx), m_offset); moveColor(static_cast<int>(m_idx), m_offset);
return {};
} }
ox::Error MoveColorCommand::undo() noexcept { void MoveColorCommand::undo() noexcept {
moveColor(static_cast<int>(m_idx) + m_offset, -m_offset); moveColor(static_cast<int>(m_idx) + m_offset, -m_offset);
return {};
} }
void MoveColorCommand::moveColor(int idx, int offset) noexcept { void MoveColorCommand::moveColor(int idx, int offset) noexcept {

View File

@ -35,9 +35,9 @@ class AddPageCommand: public studio::UndoCommand {
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
}; };
@ -55,9 +55,9 @@ class DuplicatePageCommand: public studio::UndoCommand {
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
[[nodiscard]] [[nodiscard]]
size_t insertIdx() const noexcept; size_t insertIdx() const noexcept;
@ -78,9 +78,9 @@ class RemovePageCommand: public studio::UndoCommand {
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
}; };
@ -99,9 +99,9 @@ class AddColorCommand: public studio::UndoCommand {
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept override; int commandId() const noexcept override;
ox::Error redo() noexcept override; void redo() noexcept override;
ox::Error undo() noexcept override; void undo() noexcept override;
}; };
@ -120,9 +120,9 @@ class RemoveColorCommand: public studio::UndoCommand {
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept override; int commandId() const noexcept override;
ox::Error redo() noexcept override; void redo() noexcept override;
ox::Error undo() noexcept override; void undo() noexcept override;
}; };
@ -140,14 +140,14 @@ class UpdateColorCommand: public studio::UndoCommand {
~UpdateColorCommand() noexcept override = default; ~UpdateColorCommand() noexcept override = default;
[[nodiscard]] [[nodiscard]]
bool mergeWith(const UndoCommand &cmd) noexcept final; bool mergeWith(const UndoCommand *cmd) noexcept final;
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
}; };
@ -167,9 +167,9 @@ class MoveColorCommand: public studio::UndoCommand {
int commandId() const noexcept override; int commandId() const noexcept override;
public: public:
ox::Error redo() noexcept override; void redo() noexcept override;
ox::Error undo() noexcept override; void undo() noexcept override;
private: private:
void moveColor(int idx, int offset) noexcept; void moveColor(int idx, int offset) noexcept;

View File

@ -24,7 +24,7 @@ AddSubSheetCommand::AddSubSheetCommand(
} }
} }
ox::Error AddSubSheetCommand::redo() noexcept { void AddSubSheetCommand::redo() noexcept {
auto &parent = getSubSheet(m_img, m_parentIdx); auto &parent = getSubSheet(m_img, m_parentIdx);
if (m_addedSheets.size() < 2) { if (m_addedSheets.size() < 2) {
auto i = parent.subsheets.size(); auto i = parent.subsheets.size();
@ -35,10 +35,9 @@ ox::Error AddSubSheetCommand::redo() noexcept {
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);
} }
return {};
} }
ox::Error AddSubSheetCommand::undo() noexcept { void AddSubSheetCommand::undo() noexcept {
auto &parent = getSubSheet(m_img, m_parentIdx); auto &parent = getSubSheet(m_img, m_parentIdx);
if (parent.subsheets.size() == 2) { if (parent.subsheets.size() == 2) {
auto s = parent.subsheets[0]; auto s = parent.subsheets[0];
@ -48,10 +47,9 @@ ox::Error AddSubSheetCommand::undo() noexcept {
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) {
oxReturnError(rmSubSheet(m_img, *idx)); oxLogError(rmSubSheet(m_img, *idx));
} }
} }
return {};
} }
int AddSubSheetCommand::commandId() const noexcept { int AddSubSheetCommand::commandId() const noexcept {

View File

@ -17,9 +17,9 @@ class AddSubSheetCommand: public TileSheetCommand {
public: public:
AddSubSheetCommand(TileSheet &img, TileSheet::SubSheetIdx parentIdx) noexcept; AddSubSheetCommand(TileSheet &img, TileSheet::SubSheetIdx parentIdx) noexcept;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;

View File

@ -41,20 +41,18 @@ CutPasteCommand::CutPasteCommand(
} }
} }
ox::Error CutPasteCommand::redo() noexcept { void CutPasteCommand::redo() noexcept {
auto &subsheet = getSubSheet(m_img, m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &c : m_changes) { for (const auto &c : m_changes) {
setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.newPalIdx)); setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.newPalIdx));
} }
return {};
} }
ox::Error CutPasteCommand::undo() noexcept { void CutPasteCommand::undo() noexcept {
auto &subsheet = getSubSheet(m_img, m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &c : m_changes) { for (const auto &c : m_changes) {
setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx)); setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx));
} }
return {};
} }
int CutPasteCommand::commandId() const noexcept { int CutPasteCommand::commandId() const noexcept {

View File

@ -69,9 +69,9 @@ class CutPasteCommand: public TileSheetCommand {
ox::Point const&dstEnd, ox::Point const&dstEnd,
TileSheetClipboard const&cb) noexcept; TileSheetClipboard const&cb) noexcept;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;

View File

@ -28,7 +28,7 @@ core::DeleteTilesCommand::DeleteTilesCommand(
} }
} }
ox::Error core::DeleteTilesCommand::redo() noexcept { void core::DeleteTilesCommand::redo() noexcept {
auto &s = getSubSheet(m_img, m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
auto srcPos = m_deletePos + m_deleteSz; auto srcPos = m_deletePos + m_deleteSz;
@ -37,10 +37,9 @@ ox::Error core::DeleteTilesCommand::redo() noexcept {
const auto dst2 = p.data() + (p.size() - m_deleteSz); const auto dst2 = p.data() + (p.size() - m_deleteSz);
ox::memmove(dst1, src, p.size() - srcPos); ox::memmove(dst1, src, p.size() - srcPos);
ox::memset(dst2, 0, m_deleteSz * sizeof(decltype(p[0]))); ox::memset(dst2, 0, m_deleteSz * sizeof(decltype(p[0])));
return {};
} }
ox::Error DeleteTilesCommand::undo() noexcept { void DeleteTilesCommand::undo() noexcept {
auto &s = getSubSheet(m_img, m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
const auto src = p.data() + m_deletePos; const auto src = p.data() + m_deletePos;
@ -49,7 +48,6 @@ ox::Error DeleteTilesCommand::undo() noexcept {
const auto sz = p.size() - m_deletePos - m_deleteSz; const auto sz = p.size() - m_deletePos - m_deleteSz;
ox::memmove(dst1, src, sz); ox::memmove(dst1, src, sz);
ox::memcpy(dst2, m_deletedPixels.data(), m_deletedPixels.size()); ox::memcpy(dst2, m_deletedPixels.data(), m_deletedPixels.size());
return {};
} }
int DeleteTilesCommand::commandId() const noexcept { int DeleteTilesCommand::commandId() const noexcept {

View File

@ -23,9 +23,9 @@ class DeleteTilesCommand: public TileSheetCommand {
std::size_t tileIdx, std::size_t tileIdx,
std::size_t tileCnt) noexcept; std::size_t tileCnt) noexcept;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;

View File

@ -56,20 +56,18 @@ bool DrawCommand::append(const ox::Vector<std::size_t> &idxList) noexcept {
return out; return out;
} }
ox::Error DrawCommand::redo() noexcept { void DrawCommand::redo() noexcept {
auto &subsheet = getSubSheet(m_img, m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &c : m_changes) { for (const auto &c : m_changes) {
setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(m_palIdx)); setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(m_palIdx));
} }
return {};
} }
ox::Error DrawCommand::undo() noexcept { void DrawCommand::undo() noexcept {
auto &subsheet = getSubSheet(m_img, m_subSheetIdx); auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &c : m_changes) { for (const auto &c : m_changes) {
setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx)); setPixel(subsheet, m_img.bpp, c.idx, static_cast<uint8_t>(c.oldPalIdx));
} }
return {};
} }
int DrawCommand::commandId() const noexcept { int DrawCommand::commandId() const noexcept {

View File

@ -40,9 +40,9 @@ class DrawCommand: public TileSheetCommand {
bool append(const ox::Vector<std::size_t> &idxList) noexcept; bool append(const ox::Vector<std::size_t> &idxList) noexcept;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;

View File

@ -28,7 +28,7 @@ core::InsertTilesCommand::InsertTilesCommand(
} }
} }
ox::Error InsertTilesCommand::redo() noexcept { void InsertTilesCommand::redo() noexcept {
auto &s = getSubSheet(m_img, m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
auto dstPos = m_insertPos + m_insertCnt; auto dstPos = m_insertPos + m_insertCnt;
@ -36,10 +36,9 @@ ox::Error InsertTilesCommand::redo() noexcept {
const auto src = p.data() + m_insertPos; const auto src = p.data() + m_insertPos;
ox::memmove(dst, src, p.size() - dstPos); ox::memmove(dst, src, p.size() - dstPos);
ox::memset(src, 0, m_insertCnt * sizeof(decltype(p[0]))); ox::memset(src, 0, m_insertCnt * sizeof(decltype(p[0])));
return {};
} }
ox::Error InsertTilesCommand::undo() noexcept { void InsertTilesCommand::undo() noexcept {
auto &s = getSubSheet(m_img, m_idx); auto &s = getSubSheet(m_img, m_idx);
auto &p = s.pixels; auto &p = s.pixels;
const auto srcIdx = m_insertPos + m_insertCnt; const auto srcIdx = m_insertPos + m_insertCnt;
@ -49,7 +48,6 @@ ox::Error InsertTilesCommand::undo() noexcept {
const auto sz = p.size() - srcIdx; const auto sz = p.size() - srcIdx;
ox::memmove(dst1, src, sz); ox::memmove(dst1, src, sz);
ox::memcpy(dst2, m_deletedPixels.data(), m_deletedPixels.size()); ox::memcpy(dst2, m_deletedPixels.data(), m_deletedPixels.size());
return {};
} }
int InsertTilesCommand::commandId() const noexcept { int InsertTilesCommand::commandId() const noexcept {

View File

@ -23,9 +23,9 @@ class InsertTilesCommand: public TileSheetCommand {
std::size_t tileIdx, std::size_t tileIdx,
std::size_t tileCnt) noexcept; std::size_t tileCnt) noexcept;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;

View File

@ -16,14 +16,12 @@ core::PaletteChangeCommand::PaletteChangeCommand(
m_newPalette(ox::FileAddress(ox::sfmt<ox::IString<43>>("uuid://{}", newPalette))) { m_newPalette(ox::FileAddress(ox::sfmt<ox::IString<43>>("uuid://{}", newPalette))) {
} }
ox::Error PaletteChangeCommand::redo() noexcept { void PaletteChangeCommand::redo() noexcept {
m_img.defaultPalette = m_newPalette; m_img.defaultPalette = m_newPalette;
return {};
} }
ox::Error PaletteChangeCommand::undo() noexcept { void PaletteChangeCommand::undo() noexcept {
m_img.defaultPalette = m_oldPalette; m_img.defaultPalette = m_oldPalette;
return {};
} }
int PaletteChangeCommand::commandId() const noexcept { int PaletteChangeCommand::commandId() const noexcept {

View File

@ -21,9 +21,9 @@ class PaletteChangeCommand: public TileSheetCommand {
TileSheet &img, TileSheet &img,
ox::CRStringView newPalette) noexcept; ox::CRStringView newPalette) noexcept;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;

View File

@ -11,20 +11,19 @@ core::RmSubSheetCommand::RmSubSheetCommand(TileSheet &img, TileSheet::SubSheetId
m_idx(std::move(idx)), m_idx(std::move(idx)),
m_parentIdx(m_idx) { m_parentIdx(m_idx) {
m_parentIdx.pop_back(); m_parentIdx.pop_back();
auto &parent = getSubSheet(m_img, m_parentIdx);
m_sheet = parent.subsheets[*m_idx.back().value];
} }
ox::Error RmSubSheetCommand::redo() noexcept { void RmSubSheetCommand::redo() noexcept {
auto &parent = getSubSheet(m_img, m_parentIdx); auto &parent = getSubSheet(m_img, m_parentIdx);
m_sheet = std::move(parent.subsheets[*m_idx.back().value]); oxLogError(parent.subsheets.erase(*m_idx.back().value).error);
oxReturnError(parent.subsheets.erase(*m_idx.back().value).error);
return {};
} }
ox::Error RmSubSheetCommand::undo() noexcept { void RmSubSheetCommand::undo() noexcept {
auto &parent = getSubSheet(m_img, m_parentIdx); auto &parent = getSubSheet(m_img, m_parentIdx);
auto const i = *m_idx.back().value; auto i = *m_idx.back().value;
parent.subsheets.insert(i, std::move(m_sheet)); parent.subsheets.insert(i, m_sheet);
return {};
} }
int RmSubSheetCommand::commandId() const noexcept { int RmSubSheetCommand::commandId() const noexcept {

View File

@ -18,9 +18,9 @@ class RmSubSheetCommand: public TileSheetCommand {
public: public:
RmSubSheetCommand(TileSheet &img, TileSheet::SubSheetIdx idx) noexcept; RmSubSheetCommand(TileSheet &img, TileSheet::SubSheetIdx idx) noexcept;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;

View File

@ -20,17 +20,17 @@ core::UpdateSubSheetCommand::UpdateSubSheetCommand(
m_newRows(rows) { m_newRows(rows) {
} }
ox::Error UpdateSubSheetCommand::redo() noexcept { void UpdateSubSheetCommand::redo() noexcept {
auto &sheet = getSubSheet(m_img, m_idx); auto &sheet = getSubSheet(m_img, m_idx);
sheet.name = m_newName; sheet.name = m_newName;
oxLogError(resizeSubsheet(sheet, m_img.bpp, {m_newCols, m_newRows})); sheet.columns = m_newCols;
return {}; sheet.rows = m_newRows;
oxLogError(setPixelCount(sheet, m_img.bpp, static_cast<std::size_t>(PixelsPerTile * m_newCols * m_newRows)));
} }
ox::Error UpdateSubSheetCommand::undo() noexcept { void UpdateSubSheetCommand::undo() noexcept {
auto &sheet = getSubSheet(m_img, m_idx); auto &sheet = getSubSheet(m_img, m_idx);
sheet = m_sheet; sheet = m_sheet;
return {};
} }
int UpdateSubSheetCommand::commandId() const noexcept { int UpdateSubSheetCommand::commandId() const noexcept {

View File

@ -25,9 +25,9 @@ class UpdateSubSheetCommand: public TileSheetCommand {
int cols, int cols,
int rows) noexcept; int rows) noexcept;
ox::Error redo() noexcept final; void redo() noexcept final;
ox::Error undo() noexcept final; void undo() noexcept final;
[[nodiscard]] [[nodiscard]]
int commandId() const noexcept final; int commandId() const noexcept final;

View File

@ -305,7 +305,7 @@ void TileSheetEditorModel::getFillPixels(bool *pixels, ox::Point const&pt, int o
} }
void TileSheetEditorModel::pushCommand(studio::UndoCommand *cmd) noexcept { void TileSheetEditorModel::pushCommand(studio::UndoCommand *cmd) noexcept {
std::ignore = m_undoStack.push(ox::UPtr<studio::UndoCommand>(cmd)); m_undoStack.push(ox::UPtr<studio::UndoCommand>(cmd));
m_ongoingDrawCommand = dynamic_cast<DrawCommand*>(cmd); m_ongoingDrawCommand = dynamic_cast<DrawCommand*>(cmd);
m_updated = true; m_updated = true;
} }

View File

@ -15,11 +15,11 @@ std::size_t idx(TileSheet::SubSheet const&ss, ox::Point const&pt) noexcept {
} }
[[nodiscard]] [[nodiscard]]
static TileSheet::SubSheet const *getSubsheet(TileSheet::SubSheet const&ss, SubSheetId const id) noexcept { static TileSheet::SubSheet const*getSubsheet(TileSheet::SubSheet const&ss, SubSheetId const id) noexcept {
if (ss.id == id) { if (ss.id == id) {
return &ss; return &ss;
} }
for (auto const&child: ss.subsheets) { for (auto const&child : ss.subsheets) {
if (auto out = getSubsheet(child, id)) { if (auto out = getSubsheet(child, id)) {
return out; return out;
} }
@ -34,7 +34,7 @@ static size_t getTileCnt(TileSheet::SubSheet const&ss, int const bpp) noexcept {
return ss.pixels.size() / bytesPerTile; return ss.pixels.size() / bytesPerTile;
} else { } else {
size_t out{}; size_t out{};
for (auto const&child: ss.subsheets) { for (auto const&child : ss.subsheets) {
out += getTileCnt(child, bpp); out += getTileCnt(child, bpp);
} }
return out; return out;
@ -45,7 +45,7 @@ size_t getTileCnt(TileSheet const&ts) noexcept {
return getTileCnt(ts.subsheet, ts.bpp); return getTileCnt(ts.subsheet, ts.bpp);
} }
TileSheet::SubSheet const *getSubsheet(TileSheet const&ts, SubSheetId const id) noexcept { TileSheet::SubSheet const*getSubsheet(TileSheet const&ts, SubSheetId const id) noexcept {
return getSubsheet(ts.subsheet, id); return getSubsheet(ts.subsheet, id);
} }
@ -54,7 +54,7 @@ static ox::Optional<size_t> getPixelIdx(
SubSheetId const id, SubSheetId const id,
size_t idx, size_t idx,
int8_t const bpp) noexcept { int8_t const bpp) noexcept {
for (auto const&child: ss.subsheets) { for (auto const&child : ss.subsheets) {
if (child.id == id) { if (child.id == id) {
return ox::Optional<size_t>(ox::in_place, idx); return ox::Optional<size_t>(ox::in_place, idx);
} }
@ -106,8 +106,8 @@ uint8_t getPixel(TileSheet::SubSheet const&ss, int8_t pBpp, ox::Point const&pt)
return getPixel(ss, pBpp, idx); return getPixel(ss, pBpp, idx);
} }
static void setPixel(ox::Vector<uint8_t> &pixels, int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept { void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept {
auto &pixel = pixels[static_cast<std::size_t>(idx / 2)]; auto &pixel = ss.pixels[static_cast<std::size_t>(idx / 2)];
if (pBpp == 4) { if (pBpp == 4) {
if (idx & 1) { if (idx & 1) {
pixel = static_cast<uint8_t>((pixel & 0b0000'1111) | (palIdx << 4)); pixel = static_cast<uint8_t>((pixel & 0b0000'1111) | (palIdx << 4));
@ -119,59 +119,29 @@ static void setPixel(ox::Vector<uint8_t> &pixels, int8_t pBpp, uint64_t idx, uin
} }
} }
void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, uint64_t idx, uint8_t palIdx) noexcept {
setPixel(ss.pixels, pBpp, idx, palIdx);
}
static void setPixel(ox::Vector<uint8_t> &pixels, int columns, int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept {
const auto idx = ptToIdx(pt, columns);
setPixel(pixels, pBpp, idx, palIdx);
}
void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept { void setPixel(TileSheet::SubSheet &ss, int8_t pBpp, ox::Point const&pt, uint8_t palIdx) noexcept {
const auto idx = ptToIdx(pt, ss.columns); const auto idx = ptToIdx(pt, ss.columns);
setPixel(ss, pBpp, idx, palIdx); setPixel(ss, pBpp, idx, palIdx);
} }
static ox::Error setPixelCount(ox::Vector<uint8_t> &pixels, int8_t pBpp, std::size_t cnt) noexcept { ox::Error setPixelCount(TileSheet::SubSheet &ss, int8_t pBpp, std::size_t cnt) noexcept {
switch (pBpp) { switch (pBpp) {
case 4: case 4:
pixels.resize(cnt / 2); ss.pixels.resize(cnt / 2);
return OxError(0); return OxError(0);
case 8: case 8:
pixels.resize(cnt); ss.pixels.resize(cnt);
return OxError(0); return OxError(0);
default: default:
return OxError(1, "Invalid pBpp used for TileSheet::SubSheet::setPixelCount"); return OxError(1, "Invalid pBpp used for TileSheet::SubSheet::setPixelCount");
} }
} }
ox::Error setPixelCount(TileSheet::SubSheet &ss, int8_t pBpp, std::size_t cnt) noexcept {
return setPixelCount(ss.pixels, pBpp, cnt);
}
unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept { unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept {
const auto pixelsSize = static_cast<unsigned>(ss.pixels.size()); const auto pixelsSize = static_cast<unsigned>(ss.pixels.size());
return pBpp == 4 ? pixelsSize * 2 : pixelsSize; return pBpp == 4 ? pixelsSize * 2 : pixelsSize;
} }
ox::Error resizeSubsheet(TileSheet::SubSheet &ss, int8_t pBpp, ox::Size const&sz) noexcept {
ox::Vector<uint8_t> out;
oxReturnError(setPixelCount(out, pBpp, static_cast<size_t>(sz.width * sz.height) * PixelsPerTile));
auto const w = sz.width * TileWidth;
auto const h = sz.height * TileHeight;
for (auto x = 0; x < w; ++x) {
for (auto y = 0; y < h; ++y) {
auto const palIdx = getPixel(ss, pBpp, {x, y});
setPixel(out, sz.width, pBpp, {x, y}, palIdx);
}
}
ss.columns = sz.width;
ss.rows = sz.height;
ss.pixels = std::move(out);
return {};
}
ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept { ox::Result<ox::StringView> getNameFor(TileSheet::SubSheet const&ss, SubSheetId pId) noexcept {
if (ss.id == pId) { if (ss.id == pId) {
return ox::StringView(ss.name); return ox::StringView(ss.name);

View File

@ -11,7 +11,7 @@ target_link_libraries(
target_compile_definitions( target_compile_definitions(
NostalgiaStudio PUBLIC NostalgiaStudio PUBLIC
OLYMPIC_APP_VERSION="dev build" OLYMPIC_APP_VERSION="d2024.05.0"
) )
install( install(

View File

@ -93,17 +93,9 @@ void createUuidMapping(Context &ctx, ox::StringView filePath, ox::UUID const&uui
ox::Error buildUuidMap(Context &ctx) noexcept; ox::Error buildUuidMap(Context &ctx) noexcept;
ox::Result<ox::UUID> pathToUuid(Context &ctx, ox::CRStringView path) noexcept; ox::Result<ox::String> uuidToPath(Context &ctx, ox::CRStringView uuid) noexcept;
constexpr ox::Result<ox::UUID> uuidUrlToUuid(ox::StringView uuidUrl) noexcept { ox::Result<ox::String> uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept;
return ox::UUID::fromString(substr(uuidUrl, 7));
}
ox::Result<ox::CStringView> uuidUrlToPath(Context &ctx, ox::StringView uuid) noexcept;
ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::CRStringView uuid) noexcept;
ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept;
ox::Error performPackTransforms(Context &ctx, ox::Buffer &clawData) noexcept; ox::Error performPackTransforms(Context &ctx, ox::Buffer &clawData) noexcept;

View File

@ -83,29 +83,19 @@ ox::Result<ox::UUID> pathToUuid(Context &ctx, ox::CRStringView path) noexcept {
#endif #endif
} }
ox::Result<ox::CStringView> uuidUrlToPath(Context &ctx, ox::StringView uuid) noexcept { ox::Result<ox::String> uuidToPath(Context &ctx, ox::CRStringView uuid) noexcept {
uuid = substr(uuid, 7);
#ifndef OX_BARE_METAL #ifndef OX_BARE_METAL
oxRequireM(out, ctx.uuidToPath.at(uuid)); oxRequire(out, ctx.uuidToPath.at(uuid));
return ox::CStringView(*out); return *out;
#else #else
return OxError(1, "UUID to path conversion not supported on this platform"); return OxError(1, "UUID to path conversion not supported on this platform");
#endif #endif
} }
ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::CRStringView uuid) noexcept { ox::Result<ox::String> uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept {
#ifndef OX_BARE_METAL #ifndef OX_BARE_METAL
oxRequireM(out, ctx.uuidToPath.at(uuid)); oxRequire(out, ctx.uuidToPath.at(uuid.toString()));
return ox::CStringView(*out); return *out;
#else
return OxError(1, "UUID to path conversion not supported on this platform");
#endif
}
ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::UUID const&uuid) noexcept {
#ifndef OX_BARE_METAL
oxRequireM(out, ctx.uuidToPath.at(uuid.toString()));
return ox::CStringView(*out);
#else #else
return OxError(1, "UUID to path conversion not supported on this platform"); return OxError(1, "UUID to path conversion not supported on this platform");
#endif #endif

View File

@ -30,7 +30,7 @@ static ox::Error pathToInode(
} }
if (beginsWith(path, "uuid://")) { if (beginsWith(path, "uuid://")) {
auto const uuid = ox::substr(path, 7); auto const uuid = ox::substr(path, 7);
oxReturnError(keel::uuidToPath(ctx, uuid).to<ox::String>().moveTo(path)); oxReturnError(keel::uuidToPath(ctx, uuid).moveTo(path));
} }
oxRequire(s, dest.stat(path)); oxRequire(s, dest.stat(path));
oxReturnError(o.at("type").unwrap()->set(static_cast<int8_t>(ox::FileAddressType::Inode))); oxReturnError(o.at("type").unwrap()->set(static_cast<int8_t>(ox::FileAddressType::Inode)));

View File

@ -2,7 +2,6 @@
* Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/ */
#include <algorithm>
#include <filesystem> #include <filesystem>
#include <imgui.h> #include <imgui.h>
@ -197,10 +196,10 @@ void StudioUI::drawMenu() noexcept {
if (ImGui::BeginMenu("Edit")) { if (ImGui::BeginMenu("Edit")) {
auto undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr; auto undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr;
if (ImGui::MenuItem("Undo", "Ctrl+Z", false, undoStack && undoStack->canUndo())) { if (ImGui::MenuItem("Undo", "Ctrl+Z", false, undoStack && undoStack->canUndo())) {
oxLogError(undoStack->undo()); undoStack->undo();
} }
if (ImGui::MenuItem("Redo", "Ctrl+Y", false, undoStack && undoStack->canRedo())) { if (ImGui::MenuItem("Redo", "Ctrl+Y", false, undoStack && undoStack->canRedo())) {
oxLogError(undoStack->redo()); undoStack->redo();
} }
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem("Copy", "Ctrl+C", false, m_activeEditor && m_activeEditor->copyEnabled())) { if (ImGui::MenuItem("Copy", "Ctrl+C", false, m_activeEditor && m_activeEditor->copyEnabled())) {
@ -315,14 +314,14 @@ void StudioUI::toggleProjectExplorer() noexcept {
void StudioUI::redo() noexcept { void StudioUI::redo() noexcept {
auto undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr; auto undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr;
if (undoStack && undoStack->canRedo()) { if (undoStack && undoStack->canRedo()) {
oxLogError(m_activeEditor->undoStack()->redo()); m_activeEditor->undoStack()->redo();
} }
} }
void StudioUI::undo() noexcept { void StudioUI::undo() noexcept {
auto undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr; auto undoStack = m_activeEditor ? m_activeEditor->undoStack() : nullptr;
if (undoStack && undoStack->canUndo()) { if (undoStack && undoStack->canUndo()) {
oxLogError(m_activeEditor->undoStack()->undo()); m_activeEditor->undoStack()->undo();
} }
} }

View File

@ -131,14 +131,14 @@ class Editor: public studio::BaseEditor {
[[nodiscard]] [[nodiscard]]
UndoStack *undoStack() noexcept final; UndoStack *undoStack() noexcept final;
ox::Error pushCommand(ox::UPtr<UndoCommand> &&cmd) noexcept; void pushCommand(ox::UPtr<UndoCommand> &&cmd) noexcept;
template<typename UC, typename ...Args> template<typename UC, typename ...Args>
ox::Error pushCommand(Args&&... args) noexcept { void pushCommand(Args&&... args) noexcept {
try { try {
return m_undoStack.push(ox::make_unique<UC>(ox::forward<Args>(args)...)); m_undoStack.push(ox::make_unique<UC>(ox::forward<Args>(args)...));
} catch (ox::Exception const&ex) { } catch (ox::Exception const&ex) {
return ex.toError(); oxLogError(ex.toError());
} }
} }

View File

@ -34,7 +34,7 @@ ox::Result<T> getDragDropPayload(ox::CStringView name) noexcept {
static_cast<size_t>(payload->DataSize)}); static_cast<size_t>(payload->DataSize)});
} }
ox::Error setDragDropPayload(ox::CStringView name, auto const&obj) noexcept { ox::Error setDragDropPayload(ox::CStringView name, auto const &obj) noexcept {
oxRequire(buff, ox::writeClaw(obj, ox::ClawFormat::Metal)); oxRequire(buff, ox::writeClaw(obj, ox::ClawFormat::Metal));
ImGui::SetDragDropPayload(name.c_str(), buff.data(), buff.size()); ImGui::SetDragDropPayload(name.c_str(), buff.data(), buff.size());
return {}; return {};

View File

@ -115,7 +115,7 @@ class Project {
// file. // file.
ox::Signal<ox::Error(ox::CRStringView)> fileRecognized; ox::Signal<ox::Error(ox::CRStringView)> fileRecognized;
ox::Signal<ox::Error(ox::CRStringView)> fileDeleted; ox::Signal<ox::Error(ox::CRStringView)> fileDeleted;
ox::Signal<ox::Error(ox::StringView, ox::UUID)> fileUpdated; ox::Signal<ox::Error(ox::CRStringView)> fileUpdated;
}; };
@ -135,8 +135,7 @@ ox::Error Project::writeObj(ox::CRStringView path, T const&obj, ox::ClawFormat f
oxReturnError(writeTypeStore()); oxReturnError(writeTypeStore());
} }
oxReturnError(keel::setAsset(m_ctx, path, obj)); oxReturnError(keel::setAsset(m_ctx, path, obj));
oxRequire(uuid, pathToUuid(m_ctx, path)); fileUpdated.emit(path);
fileUpdated.emit(path, uuid);
return {}; return {};
} }

View File

@ -4,26 +4,16 @@
#pragma once #pragma once
#include <source_location>
#include <ox/std/error.hpp>
namespace studio { namespace studio {
class NoChangesException: public ox::Exception {
public:
inline NoChangesException(std::source_location sloc = std::source_location::current()):
ox::Exception(sloc.file_name(), sloc.line(), 1, "Command makes no changes.") {}
};
class UndoCommand { class UndoCommand {
public: public:
virtual ~UndoCommand() noexcept = default; virtual ~UndoCommand() noexcept = default;
virtual ox::Error redo() noexcept = 0; virtual void redo() noexcept = 0;
virtual ox::Error undo() noexcept = 0; virtual void undo() noexcept = 0;
[[nodiscard]] [[nodiscard]]
virtual int commandId() const noexcept = 0; virtual int commandId() const noexcept = 0;
virtual bool mergeWith(UndoCommand const&cmd) noexcept; virtual bool mergeWith(UndoCommand const*cmd) noexcept;
}; };
} }

View File

@ -19,11 +19,11 @@ class UndoStack {
std::size_t m_stackIdx = 0; std::size_t m_stackIdx = 0;
public: public:
ox::Error push(ox::UPtr<UndoCommand> &&cmd) noexcept; void push(ox::UPtr<UndoCommand> &&cmd) noexcept;
ox::Error redo() noexcept; void redo() noexcept;
ox::Error undo() noexcept; void undo() noexcept;
[[nodiscard]] [[nodiscard]]
constexpr bool canRedo() const noexcept { constexpr bool canRedo() const noexcept {

View File

@ -127,8 +127,8 @@ ox::CStringView Editor::itemDisplayName() const noexcept {
return m_itemName; return m_itemName;
} }
ox::Error Editor::pushCommand(ox::UPtr<UndoCommand> &&cmd) noexcept { void Editor::pushCommand(ox::UPtr<UndoCommand> &&cmd) noexcept {
return m_undoStack.push(std::move(cmd)); m_undoStack.push(std::move(cmd));
} }
UndoStack *Editor::undoStack() noexcept { UndoStack *Editor::undoStack() noexcept {

View File

@ -57,7 +57,7 @@ ox::FileSystem &Project::romFs() noexcept {
ox::Error Project::mkdir(ox::CRStringView path) const noexcept { ox::Error Project::mkdir(ox::CRStringView path) const noexcept {
oxReturnError(m_fs.mkdir(path, true)); oxReturnError(m_fs.mkdir(path, true));
fileUpdated.emit(path, {}); fileUpdated.emit(path);
return {}; return {};
} }
@ -115,9 +115,9 @@ ox::Error Project::writeBuff(ox::CRStringView path, ox::Buffer const&buff) noexc
ox::Buffer outBuff; ox::Buffer outBuff;
outBuff.reserve(buff.size() + HdrSz); outBuff.reserve(buff.size() + HdrSz);
ox::BufferWriter writer(&outBuff); ox::BufferWriter writer(&outBuff);
auto const [uuid, err] = pathToUuid(m_ctx, path); auto const [uuid, err] = m_ctx.pathToUuid.at(path);
if (!err) { if (!err) {
oxReturnError(keel::writeUuidHeader(writer, uuid)); oxReturnError(keel::writeUuidHeader(writer, *uuid));
} }
oxReturnError(writer.write(buff.data(), buff.size())); oxReturnError(writer.write(buff.data(), buff.size()));
auto const newFile = m_fs.stat(path).error != 0; auto const newFile = m_fs.stat(path).error != 0;
@ -126,7 +126,7 @@ ox::Error Project::writeBuff(ox::CRStringView path, ox::Buffer const&buff) noexc
fileAdded.emit(path); fileAdded.emit(path);
indexFile(path); indexFile(path);
} else { } else {
fileUpdated.emit(path, uuid); fileUpdated.emit(path);
} }
return {}; return {};
} }

View File

@ -3,7 +3,7 @@
namespace studio { namespace studio {
bool UndoCommand::mergeWith(UndoCommand const&) noexcept { bool UndoCommand::mergeWith(UndoCommand const*) noexcept {
return false; return false;
} }

View File

@ -6,39 +6,35 @@
namespace studio { namespace studio {
ox::Error UndoStack::push(ox::UPtr<UndoCommand> &&cmd) noexcept { void UndoStack::push(ox::UPtr<UndoCommand> &&cmd) noexcept {
for (auto const i = m_stackIdx; i < m_stack.size();) { for (auto const i = m_stackIdx; i < m_stack.size();) {
std::ignore = m_stack.erase(i); std::ignore = m_stack.erase(i);
} }
oxReturnError(cmd->redo()); cmd->redo();
redoTriggered.emit(cmd.get()); redoTriggered.emit(cmd.get());
changeTriggered.emit(cmd.get()); changeTriggered.emit(cmd.get());
if (m_stack.empty() || !(*m_stack.back().value)->mergeWith(*cmd)) { if (m_stack.empty() || !(*m_stack.back().value)->mergeWith(cmd.get())) {
m_stack.emplace_back(std::move(cmd)); m_stack.emplace_back(std::move(cmd));
++m_stackIdx; ++m_stackIdx;
} }
return {};
} }
ox::Error UndoStack::redo() noexcept { void UndoStack::redo() noexcept {
if (m_stackIdx < m_stack.size()) { if (m_stackIdx < m_stack.size()) {
auto &c = m_stack[m_stackIdx]; auto &c = m_stack[m_stackIdx++];
oxReturnError(c->redo()); c->redo();
++m_stackIdx;
redoTriggered.emit(c.get()); redoTriggered.emit(c.get());
changeTriggered.emit(c.get()); changeTriggered.emit(c.get());
} }
return {};
} }
ox::Error UndoStack::undo() noexcept { void UndoStack::undo() noexcept {
if (m_stackIdx) { if (m_stackIdx) {
auto &c = m_stack[--m_stackIdx]; auto &c = m_stack[--m_stackIdx];
oxReturnError(c->undo()); c->undo();
undoTriggered.emit(c.get()); undoTriggered.emit(c.get());
changeTriggered.emit(c.get()); changeTriggered.emit(c.get());
} }
return {};
} }
} }