diff --git a/deps/nostalgia/.gitattributes b/deps/nostalgia/.gitattributes new file mode 100644 index 0000000..508cd80 --- /dev/null +++ b/deps/nostalgia/.gitattributes @@ -0,0 +1 @@ +sample_project text eol=lf diff --git a/deps/nostalgia/.gitignore b/deps/nostalgia/.gitignore index de4312c..db24f3e 100644 --- a/deps/nostalgia/.gitignore +++ b/deps/nostalgia/.gitignore @@ -6,12 +6,14 @@ .mypy_cache .stfolder .stignore +.vs util/scripts/__pycache__ pyenv CMakeLists.txt.user ROM.oxfs Session.vim build +cmake-build-* compile_commands.json dist graph_info.json diff --git a/deps/nostalgia/deps/buildcore/scripts/pybb.py b/deps/nostalgia/deps/buildcore/scripts/pybb.py index 4286089..f9e73a8 100755 --- a/deps/nostalgia/deps/buildcore/scripts/pybb.py +++ b/deps/nostalgia/deps/buildcore/scripts/pybb.py @@ -11,6 +11,7 @@ # "Python Busy Box" - adds cross-platform equivalents to Unix commands that # don't translate well to that other operating system +import multiprocessing import os import platform import shutil @@ -57,7 +58,11 @@ def cmake_build(base_path: str, target: Optional[str]) -> int: path = os.path.join(base_path, d) if not os.path.isdir(path): continue - args = ['cmake', '--build', path] + args = ['cmake', '--build', path, f'-j{multiprocessing.cpu_count()}'] + if path.endswith('release'): + args.append('--config=release') + elif path.endswith('debug'): + args.append('--config=debug') if target is not None: args.extend(['--target', target]) err = subprocess.run(args).returncode diff --git a/deps/nostalgia/deps/ox/src/ox/fs/filesystem/filelocation.hpp b/deps/nostalgia/deps/ox/src/ox/fs/filesystem/filelocation.hpp index 796b7e1..c9f113a 100644 --- a/deps/nostalgia/deps/ox/src/ox/fs/filesystem/filelocation.hpp +++ b/deps/nostalgia/deps/ox/src/ox/fs/filesystem/filelocation.hpp @@ -24,9 +24,6 @@ enum class FileAddressType: int8_t { Inode, }; -template -constexpr Error model(T *h, CommonPtrWith auto *fa) noexcept; - class FileAddress { template diff --git a/deps/nostalgia/deps/ox/src/ox/std/utility.hpp b/deps/nostalgia/deps/ox/src/ox/std/utility.hpp index f1e5530..fbb455d 100644 --- a/deps/nostalgia/deps/ox/src/ox/std/utility.hpp +++ b/deps/nostalgia/deps/ox/src/ox/std/utility.hpp @@ -32,9 +32,9 @@ constexpr bool cmp_equal(T const t, U const u) noexcept { if constexpr(ox::is_signed_v == ox::is_signed_v) { return t == u; } else if constexpr(ox::is_signed_v) { - return ox::Signed{t} == u; + return t >= 0 && static_cast>(t) == u; } else { - return t == ox::Signed{u}; + return u >= 0 && t == static_cast>(u); } } @@ -43,9 +43,9 @@ constexpr bool cmp_less(T const t, U const u) noexcept { if constexpr(ox::is_signed_v == ox::is_signed_v) { return t < u; } else if constexpr(ox::is_signed_v) { - return ox::Signed{t} < u; + return t >= 0 && static_cast>(t) < u; } else { - return t < ox::Signed{u}; + return u >= 0 && t < static_cast>(u); } } diff --git a/deps/nostalgia/deps/teagba/src/cstartup.cpp b/deps/nostalgia/deps/teagba/src/cstartup.cpp index e3845e0..a360346 100644 --- a/deps/nostalgia/deps/teagba/src/cstartup.cpp +++ b/deps/nostalgia/deps/teagba/src/cstartup.cpp @@ -2,6 +2,8 @@ * Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved. */ +#ifdef __GNUC__ + #include #include @@ -58,3 +60,5 @@ int c_start() { } } + +#endif diff --git a/deps/nostalgia/release-notes.md b/deps/nostalgia/release-notes.md index 0312e2f..06d6a9c 100644 --- a/deps/nostalgia/release-notes.md +++ b/deps/nostalgia/release-notes.md @@ -2,6 +2,12 @@ * PaletteEditor: Add RGB key shortcuts for focusing color channels +# d2025.05.1 + +* TileSheetEditor: Fix overrun errors when switching subsheets, clear selection + on switch (261e324acd) +* Fix new build error that occurs in MSVC (26d5048e6720c4c2d52508a6ee44c67dd9fe3ee5) + # d2025.05.0 * Add app icon for both window and file diff --git a/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/context.hpp b/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/context.hpp index d4448e2..d408df9 100644 --- a/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/context.hpp +++ b/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/context.hpp @@ -8,16 +8,12 @@ #include -#include "initparams.hpp" - namespace nostalgia::gfx { class Context; void safeDelete(Context *ctx) noexcept; -ox::Result> init(turbine::Context &tctx, InitParams const¶ms = {}) noexcept; - keel::Context &keelCtx(Context &ctx) noexcept; turbine::Context &turbineCtx(Context &ctx) noexcept; diff --git a/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp b/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp index 8f265d8..ccde7b0 100644 --- a/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp +++ b/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp @@ -11,7 +11,6 @@ #include "color.hpp" #include "context.hpp" -#include "initparams.hpp" #include "keelmodule.hpp" #include "palette.hpp" #include "ptidxconv.hpp" @@ -106,6 +105,14 @@ OX_MODEL_BEGIN(TileSheetSet) OX_MODEL_FIELD(entries) OX_MODEL_END() +struct InitParams { + bool glInstallDrawer = true; + uint_t glSpriteCount = 128; + uint_t glBlocksPerSprite = 64; +}; + +ox::Result> init(turbine::Context &tctx, InitParams const¶ms = {}) noexcept; + [[nodiscard]] int tileColumns(Context&) noexcept; diff --git a/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/initparams.hpp b/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/initparams.hpp deleted file mode 100644 index e7145d3..0000000 --- a/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/initparams.hpp +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved. - */ - -#pragma once - -#include - -namespace nostalgia::gfx { - -struct InitParams { - bool glInstallDrawer = true; - uint_t glSpriteCount = 128; - uint_t glBlocksPerSprite = 64; -}; - -} diff --git a/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/tilesheet.hpp b/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/tilesheet.hpp index 7593e09..c8b5feb 100644 --- a/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/tilesheet.hpp +++ b/deps/nostalgia/src/nostalgia/modules/gfx/include/nostalgia/gfx/tilesheet.hpp @@ -336,7 +336,7 @@ struct TileSheetV5 { [[nodiscard]] constexpr bool valid(TileSheetV5::SubSheet const&ss) noexcept { if (ss.subsheets.empty()) { - return static_cast(ss.columns * ss.rows * PixelsPerTile) == ss.pixels.size(); + return std::cmp_equal(ss.columns * ss.rows * PixelsPerTile, ss.pixels.size()); } else { return ss.pixels.empty() && ox::all_of(ss.subsheets.begin(), ss.subsheets.end(), [](TileSheetV5::SubSheet const&s) { diff --git a/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/cutpastecommand.cpp b/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/cutpastecommand.cpp index c5aa5b5..a09bdd5 100644 --- a/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/cutpastecommand.cpp +++ b/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/cutpastecommand.cpp @@ -27,11 +27,14 @@ CutPasteCommand::CutPasteCommand( TileSheet::SubSheetIdx subSheetIdx, ox::Point const&dstStart, ox::Point dstEnd, - TileSheetClipboard const&cb) noexcept: + TileSheetClipboard const&cb): m_commandId(commandId), m_img(img), m_subSheetIdx(std::move(subSheetIdx)) { auto const&ss = getSubSheet(m_img, m_subSheetIdx); + if (dstStart.x >= ss.columns * TileWidth || dstStart.y >= ss.rows * TileHeight) { + throw ox::Exception{1, "paste starts beyond the bounds of target"}; + } dstEnd.x = std::min(ss.columns * TileWidth - 1, dstEnd.x); dstEnd.y = std::min(ss.rows * TileHeight - 1, dstEnd.y); for (auto const&p : cb.pixels()) { diff --git a/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/cutpastecommand.hpp b/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/cutpastecommand.hpp index dc54f27..0ff7966 100644 --- a/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/cutpastecommand.hpp +++ b/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/commands/cutpastecommand.hpp @@ -69,7 +69,7 @@ class CutPasteCommand: public TileSheetCommand { TileSheet::SubSheetIdx subSheetIdx, ox::Point const&dstStart, ox::Point dstEnd, - TileSheetClipboard const&cb) noexcept; + TileSheetClipboard const&cb); ox::Error redo() noexcept final; diff --git a/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp b/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp index 9efc500..18b2955 100644 --- a/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp +++ b/deps/nostalgia/src/nostalgia/modules/gfx/src/studio/tilesheeteditor/tilesheeteditormodel.cpp @@ -46,13 +46,13 @@ Palette const TileSheetEditorModel::s_defaultPalette = { TileSheetEditorModel::TileSheetEditorModel( studio::Context &sctx, ox::StringParam path, studio::UndoStack &undoStack): - m_sctx(sctx), - m_tctx(m_sctx.tctx), - m_path(std::move(path)), - m_img(*readObj(keelCtx(m_tctx), m_path).unwrapThrow()), + m_sctx{sctx}, + m_tctx{m_sctx.tctx}, + m_path{std::move(path)}, + m_img{*readObj(keelCtx(m_tctx), m_path).unwrapThrow()}, // ignore failure to load palette - m_pal(readObj(keelCtx(m_tctx), m_img.defaultPalette).value), - m_undoStack(undoStack) { + m_pal{readObj(keelCtx(m_tctx), m_img.defaultPalette).value}, + m_undoStack{undoStack} { normalizeSubsheets(m_img.subsheet); m_pal.updated.connect(this, &TileSheetEditorModel::markUpdated); m_undoStack.changeTriggered.connect(this, &TileSheetEditorModel::markUpdatedCmdId); @@ -67,19 +67,27 @@ void TileSheetEditorModel::cut() { TileSheetClipboard blankCb; auto cb = ox::make_unique(); auto const&s = activeSubSheet(); - iterateSelectionRows(*m_selection, [&](int const x, int const y) { + if (iterateSelectionRows(*m_selection, [&](int const x, int const y) { auto pt = ox::Point{x, y}; auto const idx = gfx::idx(s, pt); - auto const c = getPixel(s, idx); + if (idx >= s.pixels.size()) { + return ox::Error{1, "invalid idx"}; + } + auto const c = s.pixels[idx]; pt -= m_selection->a; cb->addPixel(pt, c); blankCb.addPixel(pt, 0); - }); + return ox::Error{}; + })) { + return; + } auto const pt1 = m_selection->a; auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight}; turbine::setClipboardObject(m_tctx, std::move(cb)); - std::ignore = pushCommand(ox::make( - CommandId::Cut, m_img, m_activeSubsSheetIdx, pt1, pt2, blankCb)); + if (auto const cmd = ox::makeCatch( + CommandId::Cut, m_img, m_activeSubsSheetIdx, pt1, pt2, blankCb); cmd.ok()) { + std::ignore = pushCommand(cmd.value); + } } void TileSheetEditorModel::copy() { @@ -87,14 +95,20 @@ void TileSheetEditorModel::copy() { return; } auto cb = ox::make_unique(); - iterateSelectionRows(*m_selection, [&](int const x, int const y) { + if (iterateSelectionRows(*m_selection, [&](int const x, int const y) { auto pt = ox::Point{x, y}; auto const&s = activeSubSheet(); auto const idx = gfx::idx(s, pt); - auto const c = getPixel(s, idx); + if (idx >= s.pixels.size()) { + return ox::Error{1, "invalid idx"}; + } + auto const c = s.pixels[idx]; pt -= m_selection->a; cb->addPixel(pt, c); - }); + return ox::Error{}; + })) { + return; + } turbine::setClipboardObject(m_tctx, std::move(cb)); } @@ -111,8 +125,10 @@ void TileSheetEditorModel::paste() { auto const&s = activeSubSheet(); auto const pt1 = m_selection->a; auto const pt2 = ox::Point{s.columns * TileWidth, s.rows * TileHeight}; - std::ignore = pushCommand(ox::make( - CommandId::Paste, m_img, m_activeSubsSheetIdx, pt1, pt2, *cb)); + if (auto const cmd = ox::makeCatch( + CommandId::Paste, m_img, m_activeSubsSheetIdx, pt1, pt2, *cb); cmd.ok()) { + std::ignore = pushCommand(cmd.value); + } } bool TileSheetEditorModel::acceptsClipboardPayload() const noexcept { @@ -152,7 +168,7 @@ void TileSheetEditorModel::drawCommand(ox::Point const &pt, std::size_t const pa auto const idx = gfx::idx(activeSubSheet, pt); if (m_ongoingDrawCommand) { m_updated = m_updated || m_ongoingDrawCommand->append(idx); - } else if (getPixel(activeSubSheet, idx) != palIdx) { + } else if (activeSubSheet.pixels[idx] != palIdx) { std::ignore = pushCommand(ox::make( m_img, m_activeSubsSheetIdx, idx, static_cast(palIdx))); } @@ -213,6 +229,7 @@ ox::Error TileSheetEditorModel::updateSubsheet( void TileSheetEditorModel::setActiveSubsheet(TileSheet::SubSheetIdx const&idx) noexcept { m_activeSubsSheetIdx = idx; this->activeSubsheetChanged.emit(m_activeSubsSheetIdx); + clearSelection(); } void TileSheetEditorModel::fill(ox::Point const&pt, int const palIdx) noexcept { @@ -381,7 +398,7 @@ void TileSheetEditorModel::getFillPixels( int const oldColor) const noexcept { auto const idx = ptToIdx(pt, activeSubSheet.columns); auto const relIdx = idx % PixelsPerTile; - if (pixels[relIdx] || getPixel(activeSubSheet, idx) != oldColor) { + if (pixels[relIdx] || activeSubSheet.pixels[idx] != oldColor) { return; } // mark pixels to update @@ -419,7 +436,7 @@ void TileSheetEditorModel::setPalPath() noexcept { } ox::Error TileSheetEditorModel::pushCommand(studio::UndoCommand *cmd) noexcept { - std::ignore = m_undoStack.push(ox::UPtr{cmd}); + std::ignore = m_undoStack.push(ox::UPtr{cmd}); m_ongoingDrawCommand = dynamic_cast(cmd); m_updated = true; return {}; diff --git a/deps/nostalgia/src/olympic/keel/include/keel/pack.hpp b/deps/nostalgia/src/olympic/keel/include/keel/pack.hpp index 1bf5e21..97f19c0 100644 --- a/deps/nostalgia/src/olympic/keel/include/keel/pack.hpp +++ b/deps/nostalgia/src/olympic/keel/include/keel/pack.hpp @@ -46,47 +46,47 @@ struct GbaPlatSpec { static constexpr PtrType RomStart = 0x08000000; [[nodiscard]] - static constexpr std::size_t alignOf(const bool) noexcept { + static constexpr std::size_t alignOf(bool) noexcept { return 1; } [[nodiscard]] - static constexpr std::size_t alignOf(const uint8_t) noexcept { + static constexpr std::size_t alignOf(uint8_t) noexcept { return 1; } [[nodiscard]] - static constexpr std::size_t alignOf(const uint16_t) noexcept { + static constexpr std::size_t alignOf(uint16_t) noexcept { return 2; } [[nodiscard]] - static constexpr std::size_t alignOf(const uint32_t) noexcept { + static constexpr std::size_t alignOf(uint32_t) noexcept { return 4; } [[nodiscard]] - static constexpr std::size_t alignOf(const uint64_t) noexcept { + static constexpr std::size_t alignOf(uint64_t) noexcept { return 8; } [[nodiscard]] - static constexpr std::size_t alignOf(const int8_t) noexcept { + static constexpr std::size_t alignOf(int8_t) noexcept { return 1; } [[nodiscard]] - static constexpr std::size_t alignOf(const int16_t) noexcept { + static constexpr std::size_t alignOf(int16_t) noexcept { return 2; } [[nodiscard]] - static constexpr std::size_t alignOf(const int32_t) noexcept { + static constexpr std::size_t alignOf(int32_t) noexcept { return 4; } [[nodiscard]] - static constexpr std::size_t alignOf(const int64_t) noexcept { + static constexpr std::size_t alignOf(int64_t) noexcept { return 8; }