Compare commits

..

No commits in common. "b968ec8a910e75f326aabbc2dd7b8d6cb6253748" and "f189469926c0bd34b8ef7f7b13a337ca6152ad26" have entirely different histories.

16 changed files with 100 additions and 175 deletions

View File

@ -94,7 +94,7 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
} }
template<typename U, bool force> template<typename U, bool force>
constexpr ox::Error field(CRStringView, ox::UnionView<U, force> val) noexcept; constexpr ox::Error field(CRStringView, const ox::UnionView<U, force> val) noexcept;
template<typename T> template<typename T>
constexpr ox::Error field(CRStringView, const T *val) noexcept; constexpr ox::Error field(CRStringView, const T *val) noexcept;
@ -135,9 +135,6 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
constexpr ox::Error fieldArray(CRStringView name, ox::ModelValueArray const*val) noexcept; constexpr ox::Error fieldArray(CRStringView name, ox::ModelValueArray const*val) noexcept;
constexpr bool unionCheckAndIt() noexcept; constexpr bool unionCheckAndIt() noexcept;
[[nodiscard]]
constexpr size_t calcPadding(size_t align) const noexcept;
}; };
template<typename PlatSpec> template<typename PlatSpec>
@ -268,7 +265,7 @@ template<typename PlatSpec>
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(size_t sz, size_t align) noexcept { constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(size_t sz, size_t align) noexcept {
m_allocStack.emplace_back(static_cast<typename PlatSpec::PtrType>(m_writer.tellp())); m_allocStack.emplace_back(static_cast<typename PlatSpec::PtrType>(m_writer.tellp()));
oxReturnError(m_writer.seekp(0, ox::ios_base::end)); oxReturnError(m_writer.seekp(0, ox::ios_base::end));
auto const padding = calcPadding(align); const auto padding = m_writer.tellp() % align;
oxRequireM(a, ox::allocate(m_writer, sz + padding)); oxRequireM(a, ox::allocate(m_writer, sz + padding));
a += padding; a += padding;
oxReturnError(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
@ -281,7 +278,7 @@ constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(
std::size_t sz, size_t align, std::size_t restore) noexcept { std::size_t sz, size_t align, std::size_t restore) noexcept {
m_allocStack.emplace_back(restore, ox::ios_base::beg); m_allocStack.emplace_back(restore, ox::ios_base::beg);
oxReturnError(m_writer.seekp(0, ox::ios_base::end)); oxReturnError(m_writer.seekp(0, ox::ios_base::end));
auto const padding = calcPadding(align); const auto padding = m_writer.tellp() % align;
oxRequireM(a, ox::allocate(m_writer, sz + padding)); oxRequireM(a, ox::allocate(m_writer, sz + padding));
a += padding; a += padding;
oxReturnError(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
@ -361,7 +358,7 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size(); const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size();
const auto align = alignOf<PlatSpec>((*val)[0]); const auto align = alignOf<PlatSpec>((*val)[0]);
oxReturnError(m_writer.seekp(0, ox::ios_base::end)); oxReturnError(m_writer.seekp(0, ox::ios_base::end));
auto const padding = calcPadding(align); const auto padding = m_writer.tellp() % align;
oxRequireM(p, ox::allocate(m_writer, sz + padding)); oxRequireM(p, ox::allocate(m_writer, sz + padding));
p += padding; p += padding;
oxReturnError(m_writer.seekp(p)); oxReturnError(m_writer.seekp(p));
@ -397,12 +394,6 @@ constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept {
return u.checkAndIterate(); return u.checkAndIterate();
} }
template<typename PlatSpec>
constexpr size_t Preloader<PlatSpec>::calcPadding(size_t align) const noexcept {
auto const excess = m_writer.tellp() % align;
return (align * (excess != 0)) - excess;
}
template<typename PlatSpec, typename T> template<typename PlatSpec, typename T>
constexpr ox::Error preload(Preloader<PlatSpec> *pl, ox::CommonPtrWith<T> auto *obj) noexcept { constexpr ox::Error preload(Preloader<PlatSpec> *pl, ox::CommonPtrWith<T> auto *obj) noexcept {
oxReturnError(model(pl->interface(), obj)); oxReturnError(model(pl->interface(), obj));

View File

@ -105,10 +105,6 @@ void TileSheetEditorImGui::paste() {
m_model.paste(); m_model.paste();
} }
bool TileSheetEditorImGui::acceptsClipboardPayload() const noexcept {
return m_model.acceptsClipboardPayload();
}
void TileSheetEditorImGui::keyStateChanged(turbine::Key key, bool down) { void TileSheetEditorImGui::keyStateChanged(turbine::Key key, bool down) {
if (!down) { if (!down) {
return; return;
@ -122,18 +118,18 @@ void TileSheetEditorImGui::keyStateChanged(turbine::Key key, bool down) {
if (!popupOpen) { if (!popupOpen) {
auto const colorCnt = pal.pages[m_model.palettePage()].size(); auto const colorCnt = pal.pages[m_model.palettePage()].size();
if (key == turbine::Key::Alpha_D) { if (key == turbine::Key::Alpha_D) {
m_tool = TileSheetTool::Draw; m_tool = Tool::Draw;
setCopyEnabled(false); setCopyEnabled(false);
setCutEnabled(false); setCutEnabled(false);
setPasteEnabled(false); setPasteEnabled(false);
m_model.clearSelection(); m_model.clearSelection();
} else if (key == turbine::Key::Alpha_S) { } else if (key == turbine::Key::Alpha_S) {
m_tool = TileSheetTool::Select; m_tool = Tool::Select;
setCopyEnabled(true); setCopyEnabled(true);
setCutEnabled(true); setCutEnabled(true);
setPasteEnabled(true); setPasteEnabled(true);
} else if (key == turbine::Key::Alpha_F) { } else if (key == turbine::Key::Alpha_F) {
m_tool = TileSheetTool::Fill; m_tool = Tool::Fill;
setCopyEnabled(false); setCopyEnabled(false);
setCutEnabled(false); setCutEnabled(false);
setPasteEnabled(false); setPasteEnabled(false);
@ -177,17 +173,17 @@ void TileSheetEditorImGui::draw(studio::StudioContext&) noexcept {
ImGui::BeginChild("ToolBox", ImVec2(m_palViewWidth - 24, 30), true); ImGui::BeginChild("ToolBox", ImVec2(m_palViewWidth - 24, 30), true);
{ {
auto const btnSz = ImVec2(45, 14); auto const btnSz = ImVec2(45, 14);
if (ImGui::Selectable("Select", m_tool == TileSheetTool::Select, 0, btnSz)) { if (ImGui::Selectable("Select", m_tool == Tool::Select, 0, btnSz)) {
m_tool = TileSheetTool::Select; m_tool = Tool::Select;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Selectable("Draw", m_tool == TileSheetTool::Draw, 0, btnSz)) { if (ImGui::Selectable("Draw", m_tool == Tool::Draw, 0, btnSz)) {
m_tool = TileSheetTool::Draw; m_tool = Tool::Draw;
m_model.clearSelection(); m_model.clearSelection();
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Selectable("Fill", m_tool == TileSheetTool::Fill, 0, btnSz)) { if (ImGui::Selectable("Fill", m_tool == Tool::Fill, 0, btnSz)) {
m_tool = TileSheetTool::Fill; m_tool = Tool::Fill;
m_model.clearSelection(); m_model.clearSelection();
} }
} }
@ -374,16 +370,16 @@ void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept {
if (io.MouseDown[0] && m_prevMouseDownPos != mousePos) { if (io.MouseDown[0] && m_prevMouseDownPos != mousePos) {
m_prevMouseDownPos = mousePos; m_prevMouseDownPos = mousePos;
switch (m_tool) { switch (m_tool) {
case TileSheetTool::Draw: case Tool::Draw:
m_view.clickDraw(fbSize, clickPos(winPos, mousePos)); m_view.clickDraw(fbSize, clickPos(winPos, mousePos));
break; break;
case TileSheetTool::Fill: case Tool::Fill:
m_view.clickFill(fbSize, clickPos(winPos, mousePos)); m_view.clickFill(fbSize, clickPos(winPos, mousePos));
break; break;
case TileSheetTool::Select: case Tool::Select:
m_view.clickSelect(fbSize, clickPos(winPos, mousePos)); m_view.clickSelect(fbSize, clickPos(winPos, mousePos));
break; break;
case TileSheetTool::None: case Tool::None:
break; break;
} }
} }
@ -400,7 +396,7 @@ void TileSheetEditorImGui::drawTileSheet(ox::Vec2 const&fbSize) noexcept {
} }
if (io.MouseReleased[0]) { if (io.MouseReleased[0]) {
m_prevMouseDownPos = {-1, -1}; m_prevMouseDownPos = {-1, -1};
m_view.releaseMouseButton(m_tool); m_view.releaseMouseButton();
} }
} }

View File

@ -16,6 +16,13 @@
namespace nostalgia::core { namespace nostalgia::core {
enum class Tool {
None,
Draw,
Fill,
Select,
};
class TileSheetEditorImGui: public studio::Editor { class TileSheetEditorImGui: public studio::Editor {
private: private:
@ -64,7 +71,7 @@ class TileSheetEditorImGui: public studio::Editor {
TileSheetEditorModel &m_model; TileSheetEditorModel &m_model;
float m_palViewWidth = 300; float m_palViewWidth = 300;
ox::Vec2 m_prevMouseDownPos; ox::Vec2 m_prevMouseDownPos;
TileSheetTool m_tool = TileSheetTool::Draw; Tool m_tool = Tool::Draw;
public: public:
TileSheetEditorImGui(studio::StudioContext &sctx, ox::CRStringView path); TileSheetEditorImGui(studio::StudioContext &sctx, ox::CRStringView path);
@ -79,9 +86,6 @@ class TileSheetEditorImGui: public studio::Editor {
void paste() override; void paste() override;
[[nodiscard]]
bool acceptsClipboardPayload() const noexcept override;
void keyStateChanged(turbine::Key key, bool down) override; void keyStateChanged(turbine::Key key, bool down) override;
void draw(studio::StudioContext&) noexcept override; void draw(studio::StudioContext&) noexcept override;

View File

@ -55,63 +55,55 @@ TileSheetEditorModel::TileSheetEditorModel(studio::StudioContext &sctx, ox::Stri
} }
void TileSheetEditorModel::cut() { void TileSheetEditorModel::cut() {
if (!m_selection) {
return;
}
TileSheetClipboard blankCb; TileSheetClipboard blankCb;
auto cb = ox::make_unique<TileSheetClipboard>(); auto cb = ox::make_unique<TileSheetClipboard>();
auto const&s = activeSubSheet(); const auto &s = activeSubSheet();
iterateSelectionRows(*m_selection, [&](int x, int y) { for (int y = m_selectionBounds.y; y <= m_selectionBounds.y2(); ++y) {
auto pt = ox::Point{x, y}; for (int x = m_selectionBounds.x; x <= m_selectionBounds.x2(); ++x) {
auto const idx = core::idx(s, pt); auto pt = ox::Point(x, y);
auto const c = getPixel(s, m_img.bpp, idx); const auto idx = core::idx(s, pt);
pt -= m_selection->a; const auto c = getPixel(s, m_img.bpp, idx);
cb->addPixel(pt, c); pt.x -= m_selectionBounds.x;
blankCb.addPixel(pt, 0); pt.y -= m_selectionBounds.y;
}); cb->addPixel(pt, c);
auto const pt1 = m_selection->a; blankCb.addPixel(pt, 0);
auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight}; }
}
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_tctx, std::move(cb)); turbine::setClipboardObject(m_tctx, std::move(cb));
pushCommand(ox::make<CutPasteCommand>(CommandId::Cut, m_img, m_activeSubsSheetIdx, pt1, pt2, blankCb)); pushCommand(ox::make<CutPasteCommand>(CommandId::Cut, m_img, m_activeSubsSheetIdx, pt1, pt2, blankCb));
} }
void TileSheetEditorModel::copy() { void TileSheetEditorModel::copy() {
if (!m_selection) {
return;
}
auto cb = ox::make_unique<TileSheetClipboard>(); auto cb = ox::make_unique<TileSheetClipboard>();
iterateSelectionRows(*m_selection, [&](int x, int y) { for (int y = m_selectionBounds.y; y <= m_selectionBounds.y2(); ++y) {
auto pt = ox::Point{x, y}; for (int x = m_selectionBounds.x; x <= m_selectionBounds.x2(); ++x) {
const auto&s = activeSubSheet(); auto pt = ox::Point(x, y);
const auto idx = core::idx(s, pt); const auto &s = activeSubSheet();
const auto c = getPixel(s, m_img.bpp, idx); const auto idx = core::idx(s, pt);
pt -= m_selection->a; const auto c = getPixel(s, m_img.bpp, idx);
cb->addPixel(pt, c); pt.x -= m_selectionBounds.x;
}); pt.y -= m_selectionBounds.y;
cb->addPixel(pt, c);
}
}
turbine::setClipboardObject(m_tctx, std::move(cb)); turbine::setClipboardObject(m_tctx, std::move(cb));
} }
void TileSheetEditorModel::paste() { void TileSheetEditorModel::paste() {
if (!m_selection) {
return;
}
auto [cb, err] = turbine::getClipboardObject<TileSheetClipboard>(m_tctx); auto [cb, err] = turbine::getClipboardObject<TileSheetClipboard>(m_tctx);
if (err) { if (err) {
oxLogError(err); oxLogError(err);
oxErrf("Could not read clipboard: {}", toStr(err)); oxErrf("Could not read clipboard: {}", toStr(err));
return; return;
} }
auto const&s = activeSubSheet(); const auto &s = activeSubSheet();
auto const pt1 = m_selection->a; const auto pt1 = m_selectionOrigin == ox::Point(-1, -1) ? ox::Point(0, 0) : m_selectionOrigin;
auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight}; const auto pt2 = ox::Point(s.columns * TileWidth, s.rows * TileHeight);
pushCommand(ox::make<CutPasteCommand>(CommandId::Paste, m_img, m_activeSubsSheetIdx, pt1, pt2, *cb)); pushCommand(ox::make<CutPasteCommand>(CommandId::Paste, m_img, m_activeSubsSheetIdx, pt1, pt2, *cb));
} }
bool TileSheetEditorModel::acceptsClipboardPayload() const noexcept {
auto const cb = getClipboardObject<TileSheetClipboard>(m_tctx);
return cb.ok();
}
ox::StringView TileSheetEditorModel::palPath() const noexcept { ox::StringView TileSheetEditorModel::palPath() const noexcept {
auto [path, err] = m_img.defaultPalette.getPath(); auto [path, err] = m_img.defaultPalette.getPath();
if (err) { if (err) {
@ -214,26 +206,30 @@ void TileSheetEditorModel::fill(ox::Point const&pt, int palIdx) noexcept {
} }
void TileSheetEditorModel::select(ox::Point const&pt) noexcept { void TileSheetEditorModel::select(ox::Point const&pt) noexcept {
if (m_selTracker.updateCursorPoint(pt)) { if (!m_selectionOngoing) {
m_selection.emplace(m_selTracker.selection()); m_selectionOrigin = pt;
m_selectionOngoing = true;
m_selectionBounds = {pt, pt};
m_updated = true;
} else if (m_selectionBounds.pt2() != pt) {
m_selectionBounds = {m_selectionOrigin, pt};
m_updated = true; m_updated = true;
} }
} }
void TileSheetEditorModel::completeSelection() noexcept { void TileSheetEditorModel::completeSelection() noexcept {
if (m_selTracker.selectionOngoing()) { m_selectionOngoing = false;
m_selTracker.finishSelection(); auto &s = activeSubSheet();
m_selection.emplace(m_selTracker.selection()); auto pt = m_selectionBounds.pt2();
auto&pt = m_selection->b; pt.x = ox::min(s.columns * TileWidth, pt.x);
auto&s = activeSubSheet(); pt.y = ox::min(s.rows * TileHeight, pt.y);
pt.x = ox::min(s.columns * TileWidth - 1, pt.x); m_selectionBounds.setPt2(pt);
pt.y = ox::min(s.rows * TileHeight - 1, pt.y);
}
} }
void TileSheetEditorModel::clearSelection() noexcept { void TileSheetEditorModel::clearSelection() noexcept {
m_updated = true; m_updated = true;
m_selection.reset(); m_selectionOrigin = {-1, -1};
m_selectionBounds = {{-1, -1}, {-1, -1}};
} }
bool TileSheetEditorModel::updated() const noexcept { bool TileSheetEditorModel::updated() const noexcept {
@ -270,9 +266,9 @@ ox::Error TileSheetEditorModel::saveFile() noexcept {
} }
bool TileSheetEditorModel::pixelSelected(std::size_t idx) const noexcept { bool TileSheetEditorModel::pixelSelected(std::size_t idx) const noexcept {
auto const&s = activeSubSheet(); const auto &s = activeSubSheet();
auto const pt = idxToPt(static_cast<int>(idx), s.columns); const auto pt = idxToPt(static_cast<int>(idx), s.columns);
return m_selection && m_selection->contains(pt); return m_selectionBounds.contains(pt);
} }
void TileSheetEditorModel::getFillPixels(bool *pixels, ox::Point const&pt, int oldColor) const noexcept { void TileSheetEditorModel::getFillPixels(bool *pixels, ox::Point const&pt, int oldColor) const noexcept {

View File

@ -33,9 +33,10 @@ class TileSheetEditorModel: public ox::SignalHandler {
size_t m_palettePage{}; size_t m_palettePage{};
studio::UndoStack &m_undoStack; studio::UndoStack &m_undoStack;
class DrawCommand *m_ongoingDrawCommand = nullptr; class DrawCommand *m_ongoingDrawCommand = nullptr;
studio::SelectionTracker m_selTracker;
ox::Optional<studio::Selection> m_selection;
bool m_updated = false; bool m_updated = false;
bool m_selectionOngoing = false;
ox::Point m_selectionOrigin = {-1, -1};
ox::Bounds m_selectionBounds = {{-1, -1}, {-1, -1}};
public: public:
TileSheetEditorModel(studio::StudioContext &sctx, ox::StringView path, studio::UndoStack &undoStack); TileSheetEditorModel(studio::StudioContext &sctx, ox::StringView path, studio::UndoStack &undoStack);
@ -48,9 +49,6 @@ class TileSheetEditorModel: public ox::SignalHandler {
void paste(); void paste();
[[nodiscard]]
bool acceptsClipboardPayload() const noexcept;
[[nodiscard]] [[nodiscard]]
constexpr TileSheet const&img() const noexcept; constexpr TileSheet const&img() const noexcept;

View File

@ -84,18 +84,9 @@ void TileSheetEditorView::clickFill(ox::Vec2 const&paneSize, ox::Vec2 const&clic
m_model.fill(pt, static_cast<int>(m_palIdx)); m_model.fill(pt, static_cast<int>(m_palIdx));
} }
void TileSheetEditorView::releaseMouseButton(TileSheetTool tool) noexcept { void TileSheetEditorView::releaseMouseButton() noexcept {
switch (tool) { m_model.endDrawCommand();
case TileSheetTool::Draw: m_model.completeSelection();
m_model.endDrawCommand();
break;
case TileSheetTool::Select:
m_model.completeSelection();
break;
case TileSheetTool::Fill:
case TileSheetTool::None:
break;
}
} }
void TileSheetEditorView::resizeView(ox::Vec2 const&sz) noexcept { void TileSheetEditorView::resizeView(ox::Vec2 const&sz) noexcept {

View File

@ -18,8 +18,7 @@
namespace nostalgia::core { namespace nostalgia::core {
enum class TileSheetTool { enum class TileSheetTool: int {
None,
Select, Select,
Draw, Draw,
Fill, Fill,
@ -34,8 +33,6 @@ constexpr auto toString(TileSheetTool t) noexcept {
return "Draw"; return "Draw";
case TileSheetTool::Fill: case TileSheetTool::Fill:
return "Fill"; return "Fill";
case TileSheetTool::None:
return "None";
} }
return ""; return "";
} }
@ -69,7 +66,7 @@ class TileSheetEditorView: public ox::SignalHandler {
void clickFill(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept; void clickFill(ox::Vec2 const&paneSize, ox::Vec2 const&clickPos) noexcept;
void releaseMouseButton(TileSheetTool tool) noexcept; void releaseMouseButton() noexcept;
void scrollV(ox::Vec2 const&paneSz, float wheel, bool zoomMod) noexcept; void scrollV(ox::Vec2 const&paneSz, float wheel, bool zoomMod) noexcept;

View File

@ -86,21 +86,19 @@ ox::Error preloadObj(
ox::TypeStore &ts, ox::TypeStore &ts,
ox::FileSystem &romFs, ox::FileSystem &romFs,
ox::Preloader<PlatSpec> &pl, ox::Preloader<PlatSpec> &pl,
ox::StringView const path) noexcept { ox::CRStringView path) noexcept {
// load file // load file
oxRequireM(buff, romFs.read(path)); oxRequireM(buff, romFs.read(path));
oxRequireM(obj, keel::readAsset(ts, buff)); oxRequireM(obj, keel::readAsset(ts, buff));
if (obj.type()->preloadable) { if (obj.type()->preloadable) {
oxOutf("preloading {} as a {}\n", path, obj.type()->typeName);
// preload // preload
auto const size = ox::sizeOf<GbaPlatSpec>(&obj); oxRequire(a, pl.startAlloc(ox::sizeOf<GbaPlatSpec>(&obj), ox::alignOf<GbaPlatSpec>(obj)));
auto const alignment = ox::alignOf<GbaPlatSpec>(obj);
oxRequire(a, pl.startAlloc(size, alignment));
auto const err = ox::preload<GbaPlatSpec, ox::ModelObject>(&pl, &obj); auto const err = ox::preload<GbaPlatSpec, ox::ModelObject>(&pl, &obj);
oxReturnError(pl.endAlloc()); oxReturnError(pl.endAlloc());
oxReturnError(err); oxReturnError(err);
keel::PreloadPtr const p{.preloadAddr = a}; keel::PreloadPtr const p{.preloadAddr = static_cast<uint32_t>(a)};
oxReturnError(ox::writeMC(p).moveTo(buff)); oxReturnError(ox::writeMC(p).moveTo(buff));
oxOutf("preloaded {} as a {} @ {} to {}\n", path, obj.type()->typeName, a, a + size);
} else { } else {
// strip the Claw header (it is not needed after preloading) and write back out to dest fs // strip the Claw header (it is not needed after preloading) and write back out to dest fs
oxReturnError(ox::writeMC(obj).moveTo(buff)); oxReturnError(ox::writeMC(obj).moveTo(buff));

View File

@ -11,7 +11,7 @@
#include <keel/keel.hpp> #include <keel/keel.hpp>
static ox::Error writeFileBuff(ox::StringView path, ox::BufferView const buff) noexcept { static ox::Error writeFileBuff(ox::StringView path, ox::Buffer const&buff) noexcept {
try { try {
std::ofstream f(std::string(toStdStringView(path)), std::ios::binary); std::ofstream f(std::string(toStdStringView(path)), std::ios::binary);
f.write(buff.data(), static_cast<intptr_t>(buff.size())); f.write(buff.data(), static_cast<intptr_t>(buff.size()));
@ -39,10 +39,10 @@ static ox::Result<ox::Buffer> readFileBuff(ox::StringView path) noexcept {
} }
} }
static ox::Error generateTypes(ox::TypeStore &ts) noexcept { static ox::Error generateTypes(ox::TypeStore *ts) noexcept {
for (auto const mod : keel::modules()) { for (auto const mod : keel::modules()) {
for (auto gen : mod->types()) { for (auto gen : mod->types()) {
oxReturnError(gen(ts)); oxReturnError(gen(*ts));
} }
} }
return {}; return {};
@ -54,7 +54,7 @@ static ox::Error pack(ox::StringView argSrc, ox::StringView argRomBin, ox::Strin
ox::FileSystem32 dst(dstBuff); ox::FileSystem32 dst(dstBuff);
oxRequire(ctx, keel::init(ox::make_unique<ox::PassThroughFS>(argSrc), "keel-pack")); oxRequire(ctx, keel::init(ox::make_unique<ox::PassThroughFS>(argSrc), "keel-pack"));
keel::TypeStore ts(*ctx->rom, ox::sfmt("{}/type_descriptors", projectDataDir)); keel::TypeStore ts(*ctx->rom, ox::sfmt("{}/type_descriptors", projectDataDir));
oxReturnError(generateTypes(ts)); oxReturnError(generateTypes(&ts));
oxReturnError(keel::pack(*ctx, ts, dst)); oxReturnError(keel::pack(*ctx, ts, dst));
oxRequireM(pl, keel::GbaPreloader::make()); oxRequireM(pl, keel::GbaPreloader::make());
oxReturnError(preload(ts, dst, *pl)); oxReturnError(preload(ts, dst, *pl));
@ -62,13 +62,14 @@ static ox::Error pack(ox::StringView argSrc, ox::StringView argRomBin, ox::Strin
// resize buffer // resize buffer
oxRequire(dstSize, dst.size()); oxRequire(dstSize, dst.size());
dstBuff.resize(dstSize); dstBuff.resize(dstSize);
// concatenate ROM segments
oxRequireM(romBuff, readFileBuff(argRomBin)); oxRequireM(romBuff, readFileBuff(argRomBin));
oxOutf("Input exe size: {} bytes\n", romBuff.size()); oxReturnError(appendBinary(romBuff, dstBuff, *pl));
oxOutf("Dest FS size: {} bytes\n", dstSize); oxOutf("Dest FS size: {} bytes\n", dstSize);
oxOutf("Preload buff size: {} bytes\n", pl->buff().size()); oxOutf("Preload buff size: {} bytes\n", pl->buff().size());
oxReturnError(appendBinary(romBuff, dstBuff, *pl)); oxOutf("ROM buff size: {} bytes\n", romBuff.size());
oxOutf("Final ROM buff size: {} bytes\n", romBuff.size());
oxReturnError(writeFileBuff(argRomBin, romBuff)); oxReturnError(writeFileBuff(argRomBin, romBuff));
return {}; return {};
} }

View File

@ -34,7 +34,7 @@ static ox::Error pathToInode(
} }
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)));
oxOutf("\tpath to inode: {} => {}\n", path, s.inode); oxOutf("path to inode: {} => {}\n", path, s.inode);
return data.set(2, s.inode); return data.set(2, s.inode);
} }
@ -97,7 +97,6 @@ static ox::Error doTransformations(
oxReturnError(keel::performPackTransforms(ctx, buff)); oxReturnError(keel::performPackTransforms(ctx, buff));
// transform FileAddresses // transform FileAddresses
oxRequireM(obj, keel::readAsset(ts, buff)); oxRequireM(obj, keel::readAsset(ts, buff));
oxOutf("transforming {}\n", filePath);
oxReturnError(transformFileAddressesObj(ctx, dest, obj)); oxReturnError(transformFileAddressesObj(ctx, dest, obj));
oxReturnError(ox::writeClaw(obj).moveTo(buff)); oxReturnError(ox::writeClaw(obj).moveTo(buff));
// write file to dest // write file to dest
@ -144,15 +143,16 @@ static ox::Error copy(
if (beginsWith(name, ".")) { if (beginsWith(name, ".")) {
continue; continue;
} }
oxOutf("reading {}\n", currentFile);
oxRequire(stat, src.stat(currentFile)); oxRequire(stat, src.stat(currentFile));
if (stat.fileType == ox::FileType::Directory) { if (stat.fileType == ox::FileType::Directory) {
oxReturnError(dest.mkdir(currentFile, true)); oxReturnError(dest.mkdir(currentFile, true));
oxReturnError(copy(src, dest, currentFile + '/')); oxReturnError(copy(src, dest, currentFile + '/'));
} else { } else {
// load file // load file
oxOutf("copying file: {}\n", currentFile);
oxRequireM(buff, src.read(currentFile)); oxRequireM(buff, src.read(currentFile));
// write file to dest // write file to dest
oxOutf("writing {}\n", currentFile);
oxReturnError(dest.write(currentFile, buff)); oxReturnError(dest.write(currentFile, buff));
} }
} }

View File

@ -209,7 +209,7 @@ void StudioUI::drawMenu() noexcept {
if (ImGui::MenuItem("Cut", "Ctrl+X", false, m_activeEditor && m_activeEditor->cutEnabled())) { if (ImGui::MenuItem("Cut", "Ctrl+X", false, m_activeEditor && m_activeEditor->cutEnabled())) {
m_activeEditor->cut(); m_activeEditor->cut();
} }
if (ImGui::MenuItem("Paste", "Ctrl+V", false, m_activeEditor && m_activeEditor->pasteEnabled())) { if (ImGui::MenuItem("Paste", "Ctrl+V", false, m_activeEditor && m_activeEditor->pasteEnabled()) && m_activeEditor) {
m_activeEditor->paste(); m_activeEditor->paste();
} }
ImGui::EndMenu(); ImGui::EndMenu();

View File

@ -22,9 +22,4 @@ struct StudioContext {
ui(pUi), tctx(pTctx) {} ui(pUi), tctx(pTctx) {}
}; };
[[nodiscard]]
inline keel::Context &keelCtx(StudioContext &ctx) noexcept {
return keelCtx(ctx.tctx);
}
} }

View File

@ -43,9 +43,6 @@ class BaseEditor: public Widget {
virtual void paste(); virtual void paste();
[[nodiscard]]
virtual bool acceptsClipboardPayload() const noexcept;
virtual void exportFile(); virtual void exportFile();
virtual void keyStateChanged(turbine::Key key, bool down); virtual void keyStateChanged(turbine::Key key, bool down);

View File

@ -5,7 +5,6 @@
#include <ox/std/math.hpp> #include <ox/std/math.hpp>
#include <ox/std/point.hpp> #include <ox/std/point.hpp>
#include <ox/std/size.hpp>
#include <ox/std/typetraits.hpp> #include <ox/std/typetraits.hpp>
namespace studio { namespace studio {
@ -14,15 +13,6 @@ struct Selection {
ox::Point a, b; ox::Point a, b;
constexpr Selection() noexcept = default; constexpr Selection() noexcept = default;
constexpr Selection(ox::Point const&pA, ox::Point const&pB) noexcept: a(pA), b(pB) {} constexpr Selection(ox::Point const&pA, ox::Point const&pB) noexcept: a(pA), b(pB) {}
[[nodiscard]]
constexpr ox::Size size() const noexcept {
return {b.x - a.x, b.y - a.y};
}
[[nodiscard]]
constexpr bool contains(ox::Point const&pt) const noexcept {
return a.x <= pt.x && a.y <= pt.y
&& b.x >= pt.x && b.y >= pt.y;
}
}; };
constexpr auto iterateSelection(studio::Selection const&sel, auto const&cb) { constexpr auto iterateSelection(studio::Selection const&sel, auto const&cb) {
@ -41,22 +31,6 @@ constexpr auto iterateSelection(studio::Selection const&sel, auto const&cb) {
} }
}; };
constexpr auto iterateSelectionRows(studio::Selection const&sel, auto const&cb) {
constexpr auto retErr = ox::is_same_v<decltype(cb(0, 0)), ox::Error>;
for (auto y = sel.a.y; y <= sel.b.y; ++y) {
for (auto x = sel.a.x; x <= sel.b.x; ++x) {
if constexpr(retErr) {
oxReturnError(cb(x, y));
} else {
cb(x, y);
}
}
}
if constexpr(retErr) {
return ox::Error{};
}
};
class SelectionTracker { class SelectionTracker {
private: private:
bool m_selectionOngoing{}; bool m_selectionOngoing{};
@ -74,23 +48,14 @@ class SelectionTracker {
m_selectionOngoing = true; m_selectionOngoing = true;
} }
/** constexpr void updateCursorPoint(ox::Point cursor, bool allowStart = true) noexcept {
*
* @param cursor
* @param allowStart
* @return true if changed, false otherwise
*/
constexpr bool updateCursorPoint(ox::Point cursor, bool allowStart = true) noexcept {
auto changed = false;
if (!m_selectionOngoing && allowStart) { if (!m_selectionOngoing && allowStart) {
m_pointA = cursor; m_pointA = cursor;
m_selectionOngoing = true; m_selectionOngoing = true;
} }
if (m_selectionOngoing) { if (m_selectionOngoing) {
m_pointB = cursor; m_pointB = cursor;
changed = true;
} }
return changed;
} }
constexpr void updateCursorPoint(ox::Vec2 cursor, bool allowStart = true) noexcept { constexpr void updateCursorPoint(ox::Vec2 cursor, bool allowStart = true) noexcept {

View File

@ -23,10 +23,6 @@ void BaseEditor::copy() {
void BaseEditor::paste() { void BaseEditor::paste() {
} }
bool BaseEditor::acceptsClipboardPayload() const noexcept {
return {};
}
void BaseEditor::exportFile() { void BaseEditor::exportFile() {
} }
@ -99,7 +95,7 @@ void BaseEditor::setPasteEnabled(bool v) {
} }
bool BaseEditor::pasteEnabled() const noexcept { bool BaseEditor::pasteEnabled() const noexcept {
return m_pasteEnabled && acceptsClipboardPayload(); return m_pasteEnabled;
} }
ox::Error BaseEditor::saveItem() noexcept { ox::Error BaseEditor::saveItem() noexcept {

View File

@ -29,7 +29,7 @@ template<typename T>
class ClipboardObject: public BaseClipboardObject { class ClipboardObject: public BaseClipboardObject {
[[nodiscard]] [[nodiscard]]
ox::String typeId() const noexcept final { ox::String typeId() const noexcept final {
return ox::String(ox::ModelTypeId_v<T>); return ox::buildTypeId(T::TypeName, T::TypeVersion);
} }
}; };