From 08b9508d83a9243585d37f6d93c348651569f7db Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 26 Jul 2025 15:09:10 -0500 Subject: [PATCH 01/10] [ox/std] Give std::ignore a named type --- deps/ox/src/ox/std/ignore.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/ox/src/ox/std/ignore.hpp b/deps/ox/src/ox/std/ignore.hpp index 5dcaa5c9..52fc4254 100644 --- a/deps/ox/src/ox/std/ignore.hpp +++ b/deps/ox/src/ox/std/ignore.hpp @@ -16,7 +16,7 @@ namespace std { -inline constexpr struct { +inline constexpr struct ignore_t { constexpr void operator=(auto&&) const noexcept {} } ignore; From 16886cdf1c7fe75581e366c1099e911e8b4eede4 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 26 Jul 2025 18:29:51 -0500 Subject: [PATCH 02/10] [hull] Add start on command interpreter --- src/olympic/CMakeLists.txt | 3 + src/olympic/hull/CMakeLists.txt | 12 ++++ src/olympic/hull/hull.cpp | 98 +++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 src/olympic/hull/CMakeLists.txt create mode 100644 src/olympic/hull/hull.cpp diff --git a/src/olympic/CMakeLists.txt b/src/olympic/CMakeLists.txt index f054cdac..9661197f 100644 --- a/src/olympic/CMakeLists.txt +++ b/src/olympic/CMakeLists.txt @@ -19,6 +19,9 @@ else() endif() add_subdirectory(applib) +if(NOT APPLE) + add_subdirectory(hull) +endif() add_subdirectory(keel) add_subdirectory(turbine) if(${OLYMPIC_BUILD_STUDIO}) diff --git a/src/olympic/hull/CMakeLists.txt b/src/olympic/hull/CMakeLists.txt new file mode 100644 index 00000000..5fc56b05 --- /dev/null +++ b/src/olympic/hull/CMakeLists.txt @@ -0,0 +1,12 @@ + +add_library(Hull) +target_sources( + Hull PUBLIC + FILE_SET CXX_MODULES FILES + hull.cpp +) + +target_link_libraries( + Hull PUBLIC + OxStd +) diff --git a/src/olympic/hull/hull.cpp b/src/olympic/hull/hull.cpp new file mode 100644 index 00000000..9a9d7ca2 --- /dev/null +++ b/src/olympic/hull/hull.cpp @@ -0,0 +1,98 @@ +/* + * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +module; + +#include + +export module hull; + +namespace hull { + +export +template +constexpr ox::Result> parseCmd(ox::StringViewCR cmd) noexcept + requires(ox::is_same_v || ox::is_same_v) { + auto const tokens = split(cmd, ' '); + ox::Vector args; + char waitingFor{}; + auto const handleString = [&waitingFor, &args]( + ox::StringViewCR token, + char const delimiter) { + if (endsWith(token, delimiter)) { + args.emplace_back(substr(token, 1, token.size() - 1)); + } else { + waitingFor = delimiter; + args.emplace_back(substr(token, 1)); + } + }; + for (auto const &token : tokens) { + if (waitingFor) { + if (endsWith(token, waitingFor)) { + waitingFor = 0; + } + auto &tgt = *args.back().value; + if constexpr (ox::is_same_v) { + tgt += substr(token, 0, token.size() - 1); + } else { + tgt = {tgt.data(), tgt.size() + token.size() - 1}; + } + } else if (beginsWith(token, '"')) { + handleString(token, '"'); + } else if (beginsWith(token, '\'')) { + handleString(token, '\''); + } else { + args.emplace_back(token); + } + } + if (waitingFor) { + return ox::Error{1, "unterminated string"}; + } + return args; +} + +template +[[nodiscard]] +static constexpr bool testParse(ox::StringViewCR cmd, std::initializer_list const &expected) noexcept { + auto const [args, err] = parseCmd(cmd); + static constexpr auto equals = [](auto const &a, auto const &b) { + if (a.size() != b.size()) { + return false; + } + for (auto i = 0u; i < a.size(); ++i) { + if (a[i] != b[i]) { + return false; + } + } + return true; + }; + return !err && equals(args, ox::Vector(expected)); +} + +static_assert(testParse("echo asdf", {"echo", "asdf"})); +static_assert(testParse("echo asdf", {"echo", "asdf"})); + +static_assert(testParse("echo \"asdf\"", {"echo", "asdf"})); +static_assert(testParse("echo \"asdf\"", {"echo", "asdf"})); + +static_assert(testParse("echo 'asdf'", {"echo", "asdf"})); +static_assert(testParse("echo 'asdf'", {"echo", "asdf"})); + +static_assert(testParse("echo 'asdf' aoue", {"echo", "asdf", "aoue"})); +static_assert(testParse("echo 'asdf' aoue", {"echo", "asdf", "aoue"})); + +export class Prompt { + + private: + ox::String m_cmd; + ox::String m_workingDir{"/"}; + ox::Vector m_prevCmds; + + public: + + private: + +}; + +} From ee9a3e1152c9acecaa98292f6953a652b139be78 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 26 Jul 2025 18:30:12 -0500 Subject: [PATCH 03/10] [ox/std] Cleanup --- deps/ox/src/ox/std/string.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/deps/ox/src/ox/std/string.hpp b/deps/ox/src/ox/std/string.hpp index 8a1cb7d0..d31f58be 100644 --- a/deps/ox/src/ox/std/string.hpp +++ b/deps/ox/src/ox/std/string.hpp @@ -139,7 +139,7 @@ class BasicString { constexpr BasicString &operator+=(Integer_c auto i) noexcept; - constexpr BasicString &operator+=(StringView src) noexcept; + constexpr BasicString &operator+=(StringViewCR src) noexcept; constexpr BasicString &operator+=(BasicString const&src) noexcept; @@ -185,7 +185,7 @@ class BasicString { return {}; } - constexpr Error append(ox::StringView sv) noexcept { + constexpr Error append(StringViewCR sv) noexcept { return append(sv.data(), sv.size()); } @@ -376,7 +376,7 @@ constexpr BasicString &BasicString::operat } template -constexpr BasicString &BasicString::operator+=(StringView s) noexcept { +constexpr BasicString &BasicString::operator+=(StringViewCR s) noexcept { std::size_t strLen = s.bytes(); std::ignore = append(s.data(), strLen); return *this; @@ -456,7 +456,7 @@ constexpr bool BasicString::operator==(const char *other) con template constexpr bool BasicString::operator==(OxString_c auto const&other) const noexcept { - return ox::StringView(*this) == ox::StringView(other); + return StringView(*this) == StringView(other); } template @@ -548,28 +548,28 @@ using StringCR = String const&; [[nodiscard]] -constexpr ox::String toString(ox::StringViewCR sv) noexcept { +constexpr String toString(StringViewCR sv) noexcept { return ox::String(sv); } template [[nodiscard]] -constexpr auto sizeOf(const ox::BasicString*) noexcept { +constexpr auto sizeOf(BasicString const*) noexcept { VectorMemMap v{.smallVecSize = SmallStringSize_v}; return sizeOf(&v); } template [[nodiscard]] -constexpr auto alignOf(const ox::BasicString&) noexcept { +constexpr auto alignOf(BasicString const&) noexcept { VectorMemMap v{.smallVecSize = SmallStringSize_v}; return alignOf(&v); } template -struct MaybeView> { - using type = ox::StringView; +struct MaybeView> { + using type = StringView; }; } From 934f0c9232b450db3fca321571f6ced11fd98a16 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 26 Jul 2025 18:31:03 -0500 Subject: [PATCH 04/10] [ox/std] Add beginsWith and endsWith variants that that cingle chars --- deps/ox/src/ox/std/strops.hpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/deps/ox/src/ox/std/strops.hpp b/deps/ox/src/ox/std/strops.hpp index b2f3ec99..86251f44 100644 --- a/deps/ox/src/ox/std/strops.hpp +++ b/deps/ox/src/ox/std/strops.hpp @@ -21,7 +21,7 @@ OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage) namespace ox { [[nodiscard]] -constexpr ox::StringView substr(ox::StringView const&str, std::size_t pos) noexcept { +constexpr StringView substr(StringViewCR str, std::size_t const pos) noexcept { if (str.size() >= pos) { return {&str[pos], str.size() - pos}; } @@ -29,13 +29,23 @@ constexpr ox::StringView substr(ox::StringView const&str, std::size_t pos) noexc } [[nodiscard]] -constexpr ox::StringView substr(ox::StringView const&str, std::size_t start, std::size_t end) noexcept { +constexpr StringView substr(StringViewCR str, std::size_t const start, std::size_t const end) noexcept { if (str.size() >= start && end >= start) { return {&str[start], end - start}; } return {}; } +[[nodiscard]] +constexpr bool beginsWith(StringViewCR base, char const beginning) noexcept { + return base.size() && base[0] == beginning; +} + +[[nodiscard]] +constexpr bool endsWith(StringViewCR base, char const ending) noexcept { + return base.size() && base[base.size() - 1] == ending; +} + [[nodiscard]] constexpr bool beginsWith(StringViewCR base, StringViewCR beginning) noexcept { const auto beginningLen = ox::min(beginning.size(), base.size()); @@ -49,7 +59,7 @@ constexpr bool endsWith(StringViewCR base, StringViewCR ending) noexcept { } [[nodiscard]] -constexpr std::size_t find(StringViewCR str, char search) noexcept { +constexpr std::size_t find(StringViewCR str, char const search) noexcept { std::size_t i = 0; for (; i < str.size(); ++i) { if (str[i] == search) { @@ -72,7 +82,7 @@ constexpr std::size_t find(StringViewCR str, StringViewCR search) noexcept { template [[nodiscard]] -constexpr ox::Vector split(StringViewCR str, char del) noexcept { +constexpr ox::Vector split(StringViewCR str, char const del) noexcept { ox::Vector out; constexpr auto nextSeg = [](StringViewCR current, char del) { return substr(current, find(current, del) + 1); @@ -105,7 +115,7 @@ constexpr ox::Vector split(StringViewCR str, StringView } [[nodiscard]] -constexpr ox::Result lastIndexOf(ox::StringViewCR str, int character) noexcept { +constexpr ox::Result lastIndexOf(ox::StringViewCR str, int const character) noexcept { ox::Result retval = ox::Error(1, "Character not found"); for (auto i = static_cast(str.bytes() - 1); i >= 0; --i) { if (str[static_cast(i)] == character) { From 92f74b27d16a99821cbb4b6c2e025c9ad9d45323 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 26 Jul 2025 18:31:41 -0500 Subject: [PATCH 05/10] [ox/std] Add null check for deallocating in consteval context Vector --- deps/ox/src/ox/std/vector.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index faab0650..aa570621 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -87,7 +87,9 @@ struct VectorAllocator { constexpr void deallocate(T *items, std::size_t cap) noexcept { // small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr if (std::is_constant_evaluated()) { - Allocator{}.deallocate(items, cap); + if (items) { + Allocator{}.deallocate(items, cap); + } } else { if (items && static_cast(items) != static_cast(m_data.data())) { Allocator{}.deallocate(items, cap); From fbf49ba5117d9f79667222374edbb24b6137c517 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 26 Jul 2025 18:31:55 -0500 Subject: [PATCH 06/10] [ox/std] Add pre- and post-increment operators to Span --- deps/ox/src/ox/std/span.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/deps/ox/src/ox/std/span.hpp b/deps/ox/src/ox/std/span.hpp index 871dd882..381e83eb 100644 --- a/deps/ox/src/ox/std/span.hpp +++ b/deps/ox/src/ox/std/span.hpp @@ -163,6 +163,24 @@ class Span { return *this; } + constexpr Span operator++(int) noexcept { + ++m_items; + --m_size; + if (!m_size) [[unlikely]] { + m_items = nullptr; + } + return *this; + } + + constexpr Span operator++() noexcept { + ++m_items; + --m_size; + if (!m_size) [[unlikely]] { + m_items = nullptr; + } + return *this; + } + [[nodiscard]] constexpr auto data() const noexcept { return m_items; From c275c5f5e66bc04da35e2991ab52a68170ebb9a5 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 26 Jul 2025 18:33:24 -0500 Subject: [PATCH 07/10] [hull] Disable building hull for now --- src/olympic/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/olympic/CMakeLists.txt b/src/olympic/CMakeLists.txt index 9661197f..a415516d 100644 --- a/src/olympic/CMakeLists.txt +++ b/src/olympic/CMakeLists.txt @@ -19,9 +19,9 @@ else() endif() add_subdirectory(applib) -if(NOT APPLE) - add_subdirectory(hull) -endif() +#if(NOT APPLE) +# add_subdirectory(hull) +#endif() add_subdirectory(keel) add_subdirectory(turbine) if(${OLYMPIC_BUILD_STUDIO}) From e61d4647b5757a16751c712cb411dd6255c95a8b Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Mon, 28 Jul 2025 21:54:50 -0500 Subject: [PATCH 08/10] [nostalgia/gfx] Fix BG tilesheet loading, add background offset functions --- .../modules/gfx/include/nostalgia/gfx/gfx.hpp | 8 ++++++-- src/nostalgia/modules/gfx/src/gfx-gba.cpp | 20 +++++++++++++------ src/nostalgia/modules/gfx/src/gfx.cpp | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp b/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp index 978c0a96..792bd822 100644 --- a/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp +++ b/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp @@ -238,6 +238,10 @@ void setBgCbb(Context &ctx, unsigned bgIdx, unsigned cbbIdx) noexcept; void setBgPriority(Context &ctx, uint_t bgIdx, uint_t priority) noexcept; +void setBgOffset(Context &ctx, uint16_t bg, int16_t x, int16_t y) noexcept; + +void scrollBgOffset(Context &ctx, uint16_t bg, int16_t x, int16_t y) noexcept; + void hideSprite(Context &ctx, unsigned) noexcept; void showSprite(Context &ctx, unsigned) noexcept; @@ -260,8 +264,8 @@ constexpr ox::CStringView GlslVersion = "#version 330"; [[nodiscard]] ox::Size drawSize(int scale = 5) noexcept; -void draw(gfx::Context &ctx, ox::Size const &renderSz) noexcept; +void draw(Context &ctx, ox::Size const &renderSz) noexcept; -void draw(gfx::Context&, int scale = 5) noexcept; +void draw(Context&, int scale = 5) noexcept; } diff --git a/src/nostalgia/modules/gfx/src/gfx-gba.cpp b/src/nostalgia/modules/gfx/src/gfx-gba.cpp index ad67b35b..bb6ad6f1 100644 --- a/src/nostalgia/modules/gfx/src/gfx-gba.cpp +++ b/src/nostalgia/modules/gfx/src/gfx-gba.cpp @@ -169,8 +169,8 @@ ox::Error loadBgTileSheet( unsigned const cbb, CompactTileSheet const &ts, ox::Optional const &paletteBank) noexcept { - auto const cnt = (ts.pixels.size() * PixelsPerTile) / (1 + (ts.bpp == 4)); - for (size_t i = 0; i < cnt; ++i) { + auto const cnt = ts.pixels.size() >> (ts.bpp == 4); + for (size_t i{}; i < cnt; ++i) { auto const srcIdx = i * 2; auto const p1 = static_cast(ts.pixels[srcIdx]); auto const p2 = static_cast(ts.pixels[srcIdx + 1]); @@ -218,10 +218,10 @@ ox::Error loadSpriteTileSheet( Context &ctx, CompactTileSheet const &ts, bool const loadDefaultPalette) noexcept { - for (size_t i = 0; i < ts.pixels.size(); i += 2) { - uint16_t v = ts.pixels[i]; - v |= static_cast(ts.pixels[i + 1] << 8); - MEM_SPRITE_TILES[i] = v; + for (size_t i{}; i < ts.pixels.size(); i += 2) { + MEM_SPRITE_TILES[i >> 1] = + static_cast(ts.pixels[i]) | + (static_cast(ts.pixels[i + 1]) << 8); } if (loadDefaultPalette && ts.defaultPalette) { OX_RETURN_ERROR(loadSpritePalette(ctx, ts.defaultPalette)); @@ -294,6 +294,14 @@ void setBgPriority(Context&, uint_t const bgIdx, uint_t const priority) noexcept bgCtl = (bgCtl & 0b1111'1111'1111'1100u) | (priority & 0b11); } +void setBgOffset(Context&, uint16_t const bg, int16_t const x, int16_t const y) noexcept { + teagba::setBgOffset(bg, x, y); +} + +void scrollBgOffset(Context&, uint16_t const bg, int16_t const x, int16_t const y) noexcept { + teagba::scrollBgOffset(bg, x, y); +} + void hideSprite(Context&, unsigned const idx) noexcept { //oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow"); teagba::addSpriteUpdate({ diff --git a/src/nostalgia/modules/gfx/src/gfx.cpp b/src/nostalgia/modules/gfx/src/gfx.cpp index e52ac87b..4c93a2c2 100644 --- a/src/nostalgia/modules/gfx/src/gfx.cpp +++ b/src/nostalgia/modules/gfx/src/gfx.cpp @@ -249,7 +249,7 @@ void setBgTile( } ox::Error initConsole(Context &ctx) noexcept { - constexpr ox::FileAddress TilesheetAddr = ox::StringLiteral("/TileSheets/Charset.ng"); + constexpr ox::FileAddress TilesheetAddr = ox::StringLiteral("/TileSheets/Charset.nts"); constexpr ox::FileAddress PaletteAddr = ox::StringLiteral("/Palettes/Charset.npal"); setBgStatus(ctx, 0b0001); setBgCbb(ctx, 0, 0); From fd610454d62feb0e90d92c93eed207e4185c7f1a Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 29 Jul 2025 00:30:17 -0500 Subject: [PATCH 09/10] [nostalgia/gfx] Fix compiler warning --- src/nostalgia/modules/gfx/src/gfx-gba.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nostalgia/modules/gfx/src/gfx-gba.cpp b/src/nostalgia/modules/gfx/src/gfx-gba.cpp index bb6ad6f1..a1d6ba4c 100644 --- a/src/nostalgia/modules/gfx/src/gfx-gba.cpp +++ b/src/nostalgia/modules/gfx/src/gfx-gba.cpp @@ -220,8 +220,9 @@ ox::Error loadSpriteTileSheet( bool const loadDefaultPalette) noexcept { for (size_t i{}; i < ts.pixels.size(); i += 2) { MEM_SPRITE_TILES[i >> 1] = - static_cast(ts.pixels[i]) | - (static_cast(ts.pixels[i + 1]) << 8); + static_cast( + ts.pixels[i] | + (static_cast(ts.pixels[i + 1]) << 8)); } if (loadDefaultPalette && ts.defaultPalette) { OX_RETURN_ERROR(loadSpritePalette(ctx, ts.defaultPalette)); From e27eee50f05bb437710313430e0d9cef636a66b1 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 29 Jul 2025 00:33:51 -0500 Subject: [PATCH 10/10] [teagba] Add set and scroll background offset functions --- deps/teagba/include/teagba/addresses.hpp | 40 +++++++++++++++++------- deps/teagba/include/teagba/gfx.hpp | 4 +++ deps/teagba/src/gfx.cpp | 14 ++++++++- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/deps/teagba/include/teagba/addresses.hpp b/deps/teagba/include/teagba/addresses.hpp index 23380b12..6b2e5e20 100644 --- a/deps/teagba/include/teagba/addresses.hpp +++ b/deps/teagba/include/teagba/addresses.hpp @@ -54,25 +54,41 @@ inline volatile BgCtl ®BgCtl(uintptr_t const bgIdx) noexcept { } // background horizontal scrolling registers -#define REG_BG0HOFS (*reinterpret_cast(0x0400'0010)) -#define REG_BG1HOFS (*reinterpret_cast(0x0400'0014)) -#define REG_BG2HOFS (*reinterpret_cast(0x0400'0018)) -#define REG_BG3HOFS (*reinterpret_cast(0x0400'001c)) +#define REG_BG0HOFS (*reinterpret_cast(0x0400'0010)) +#define REG_BG1HOFS (*reinterpret_cast(0x0400'0014)) +#define REG_BG2HOFS (*reinterpret_cast(0x0400'0018)) +#define REG_BG3HOFS (*reinterpret_cast(0x0400'001c)) [[nodiscard]] -volatile uint32_t ®BgHofs(auto const bgIdx) noexcept { - return *reinterpret_cast(0x0400'0010 + 4 * bgIdx); +volatile int16_t ®BgHofs(auto const bgIdx) noexcept { + return *reinterpret_cast(0x0400'0010 + 4 * bgIdx); } // background vertical scrolling registers -#define REG_BG0VOFS (*reinterpret_cast(0x0400'0012)) -#define REG_BG1VOFS (*reinterpret_cast(0x0400'0016)) -#define REG_BG2VOFS (*reinterpret_cast(0x0400'001a)) -#define REG_BG3VOFS (*reinterpret_cast(0x0400'001e)) +#define REG_BG0VOFS (*reinterpret_cast(0x0400'0012)) +#define REG_BG1VOFS (*reinterpret_cast(0x0400'0016)) +#define REG_BG2VOFS (*reinterpret_cast(0x0400'001a)) +#define REG_BG3VOFS (*reinterpret_cast(0x0400'001e)) [[nodiscard]] -volatile uint32_t ®BgVofs(auto const bgIdx) noexcept { - return *reinterpret_cast(0x0400'0012 + 4 * bgIdx); +volatile int16_t ®BgVofs(auto const bgIdx) noexcept { + return *reinterpret_cast(0x0400'0012 + 4 * bgIdx); +} + +// background scrolling registers + +struct OffsetPair { + int16_t x{}, y{}; +}; + +#define REG_BG0OFS (*reinterpret_cast(0x0400'0010)) +#define REG_BG1OFS (*reinterpret_cast(0x0400'0014)) +#define REG_BG2OFS (*reinterpret_cast(0x0400'0018)) +#define REG_BG3OFS (*reinterpret_cast(0x0400'001c)) + +[[nodiscard]] +volatile OffsetPair ®BgOfs(auto const bgIdx) noexcept { + return *reinterpret_cast(0x0400'0010 + sizeof(OffsetPair) * bgIdx); } ///////////////////////////////////////////////////////////////// diff --git a/deps/teagba/include/teagba/gfx.hpp b/deps/teagba/include/teagba/gfx.hpp index bd18bb3f..4a252122 100644 --- a/deps/teagba/include/teagba/gfx.hpp +++ b/deps/teagba/include/teagba/gfx.hpp @@ -41,4 +41,8 @@ void addSpriteUpdate(GbaSpriteAttrUpdate const &upd) noexcept; void applySpriteUpdates() noexcept; +void setBgOffset(uint16_t bg, int16_t x, int16_t y) noexcept; + +void scrollBgOffset(uint16_t bg, int16_t x, int16_t y) noexcept; + } diff --git a/deps/teagba/src/gfx.cpp b/deps/teagba/src/gfx.cpp index b458eeff..cd1e38b3 100644 --- a/deps/teagba/src/gfx.cpp +++ b/deps/teagba/src/gfx.cpp @@ -12,7 +12,7 @@ namespace teagba { static ox::Array g_spriteBuffer; -GbaSpriteAttrUpdate &spriteAttr(size_t i) noexcept { +GbaSpriteAttrUpdate &spriteAttr(size_t const i) noexcept { return g_spriteBuffer[i]; } @@ -29,4 +29,16 @@ void applySpriteUpdates() noexcept { } } +void setBgOffset(uint16_t const bg, int16_t const x, int16_t const y) noexcept { + auto &o = regBgOfs(bg); + o.x = x; + o.y = y; +} + +void scrollBgOffset(uint16_t const bg, int16_t const x, int16_t const y) noexcept { + auto &o = regBgOfs(bg); + o.x = o.x + x; + o.y = o.y + y; +} + }