Merge commit '1bfb7f99c215e2c74556bd3281f44962b8faaa96'
All checks were successful
Build / build (push) Successful in 1m35s
All checks were successful
Build / build (push) Successful in 1m35s
This commit is contained in:
2
deps/ox/src/ox/std/ignore.hpp
vendored
2
deps/ox/src/ox/std/ignore.hpp
vendored
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
inline constexpr struct {
|
inline constexpr struct ignore_t {
|
||||||
constexpr void operator=(auto&&) const noexcept {}
|
constexpr void operator=(auto&&) const noexcept {}
|
||||||
} ignore;
|
} ignore;
|
||||||
|
|
||||||
|
18
deps/ox/src/ox/std/span.hpp
vendored
18
deps/ox/src/ox/std/span.hpp
vendored
@@ -163,6 +163,24 @@ class Span {
|
|||||||
return *this;
|
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]]
|
[[nodiscard]]
|
||||||
constexpr auto data() const noexcept {
|
constexpr auto data() const noexcept {
|
||||||
return m_items;
|
return m_items;
|
||||||
|
18
deps/ox/src/ox/std/string.hpp
vendored
18
deps/ox/src/ox/std/string.hpp
vendored
@@ -139,7 +139,7 @@ class BasicString {
|
|||||||
|
|
||||||
constexpr BasicString &operator+=(Integer_c auto i) noexcept;
|
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;
|
constexpr BasicString &operator+=(BasicString const&src) noexcept;
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ class BasicString {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Error append(ox::StringView sv) noexcept {
|
constexpr Error append(StringViewCR sv) noexcept {
|
||||||
return append(sv.data(), sv.size());
|
return append(sv.data(), sv.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,7 +376,7 @@ constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operat
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator+=(StringView s) noexcept {
|
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator+=(StringViewCR s) noexcept {
|
||||||
std::size_t strLen = s.bytes();
|
std::size_t strLen = s.bytes();
|
||||||
std::ignore = append(s.data(), strLen);
|
std::ignore = append(s.data(), strLen);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -456,7 +456,7 @@ constexpr bool BasicString<SmallStringSize_v>::operator==(const char *other) con
|
|||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
constexpr bool BasicString<SmallStringSize_v>::operator==(OxString_c auto const&other) const noexcept {
|
constexpr bool BasicString<SmallStringSize_v>::operator==(OxString_c auto const&other) const noexcept {
|
||||||
return ox::StringView(*this) == ox::StringView(other);
|
return StringView(*this) == StringView(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t SmallStringSize_v>
|
template<std::size_t SmallStringSize_v>
|
||||||
@@ -548,28 +548,28 @@ using StringCR = String const&;
|
|||||||
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr ox::String toString(ox::StringViewCR sv) noexcept {
|
constexpr String toString(StringViewCR sv) noexcept {
|
||||||
return ox::String(sv);
|
return ox::String(sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename PlatSpec, std::size_t SmallStringSize_v>
|
template<typename PlatSpec, std::size_t SmallStringSize_v>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr auto sizeOf(const ox::BasicString<SmallStringSize_v>*) noexcept {
|
constexpr auto sizeOf(BasicString<SmallStringSize_v> const*) noexcept {
|
||||||
VectorMemMap<PlatSpec> v{.smallVecSize = SmallStringSize_v};
|
VectorMemMap<PlatSpec> v{.smallVecSize = SmallStringSize_v};
|
||||||
return sizeOf<PlatSpec>(&v);
|
return sizeOf<PlatSpec>(&v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename PlatSpec, std::size_t SmallStringSize_v>
|
template<typename PlatSpec, std::size_t SmallStringSize_v>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr auto alignOf(const ox::BasicString<SmallStringSize_v>&) noexcept {
|
constexpr auto alignOf(BasicString<SmallStringSize_v> const&) noexcept {
|
||||||
VectorMemMap<PlatSpec> v{.smallVecSize = SmallStringSize_v};
|
VectorMemMap<PlatSpec> v{.smallVecSize = SmallStringSize_v};
|
||||||
return alignOf<PlatSpec>(&v);
|
return alignOf<PlatSpec>(&v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t sz>
|
template<size_t sz>
|
||||||
struct MaybeView<ox::BasicString<sz>> {
|
struct MaybeView<BasicString<sz>> {
|
||||||
using type = ox::StringView;
|
using type = StringView;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
20
deps/ox/src/ox/std/strops.hpp
vendored
20
deps/ox/src/ox/std/strops.hpp
vendored
@@ -21,7 +21,7 @@ OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
|||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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) {
|
if (str.size() >= pos) {
|
||||||
return {&str[pos], 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]]
|
[[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) {
|
if (str.size() >= start && end >= start) {
|
||||||
return {&str[start], end - start};
|
return {&str[start], end - start};
|
||||||
}
|
}
|
||||||
return {};
|
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]]
|
[[nodiscard]]
|
||||||
constexpr bool beginsWith(StringViewCR base, StringViewCR beginning) noexcept {
|
constexpr bool beginsWith(StringViewCR base, StringViewCR beginning) noexcept {
|
||||||
const auto beginningLen = ox::min(beginning.size(), base.size());
|
const auto beginningLen = ox::min(beginning.size(), base.size());
|
||||||
@@ -49,7 +59,7 @@ constexpr bool endsWith(StringViewCR base, StringViewCR ending) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[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;
|
std::size_t i = 0;
|
||||||
for (; i < str.size(); ++i) {
|
for (; i < str.size(); ++i) {
|
||||||
if (str[i] == search) {
|
if (str[i] == search) {
|
||||||
@@ -72,7 +82,7 @@ constexpr std::size_t find(StringViewCR str, StringViewCR search) noexcept {
|
|||||||
|
|
||||||
template<std::size_t smallSz = 0>
|
template<std::size_t smallSz = 0>
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr ox::Vector<ox::StringView, smallSz> split(StringViewCR str, char del) noexcept {
|
constexpr ox::Vector<ox::StringView, smallSz> split(StringViewCR str, char const del) noexcept {
|
||||||
ox::Vector<ox::StringView, smallSz> out;
|
ox::Vector<ox::StringView, smallSz> out;
|
||||||
constexpr auto nextSeg = [](StringViewCR current, char del) {
|
constexpr auto nextSeg = [](StringViewCR current, char del) {
|
||||||
return substr(current, find(current, del) + 1);
|
return substr(current, find(current, del) + 1);
|
||||||
@@ -105,7 +115,7 @@ constexpr ox::Vector<ox::StringView, smallSz> split(StringViewCR str, StringView
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr ox::Result<std::size_t> lastIndexOf(ox::StringViewCR str, int character) noexcept {
|
constexpr ox::Result<std::size_t> lastIndexOf(ox::StringViewCR str, int const character) noexcept {
|
||||||
ox::Result<std::size_t> retval = ox::Error(1, "Character not found");
|
ox::Result<std::size_t> retval = ox::Error(1, "Character not found");
|
||||||
for (auto i = static_cast<int>(str.bytes() - 1); i >= 0; --i) {
|
for (auto i = static_cast<int>(str.bytes() - 1); i >= 0; --i) {
|
||||||
if (str[static_cast<std::size_t>(i)] == character) {
|
if (str[static_cast<std::size_t>(i)] == character) {
|
||||||
|
4
deps/ox/src/ox/std/vector.hpp
vendored
4
deps/ox/src/ox/std/vector.hpp
vendored
@@ -87,7 +87,9 @@ struct VectorAllocator {
|
|||||||
constexpr void deallocate(T *items, std::size_t cap) noexcept {
|
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
|
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
|
||||||
if (std::is_constant_evaluated()) {
|
if (std::is_constant_evaluated()) {
|
||||||
Allocator{}.deallocate(items, cap);
|
if (items) {
|
||||||
|
Allocator{}.deallocate(items, cap);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (items && static_cast<void*>(items) != static_cast<void*>(m_data.data())) {
|
if (items && static_cast<void*>(items) != static_cast<void*>(m_data.data())) {
|
||||||
Allocator{}.deallocate(items, cap);
|
Allocator{}.deallocate(items, cap);
|
||||||
|
40
deps/teagba/include/teagba/addresses.hpp
vendored
40
deps/teagba/include/teagba/addresses.hpp
vendored
@@ -54,25 +54,41 @@ inline volatile BgCtl ®BgCtl(uintptr_t const bgIdx) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// background horizontal scrolling registers
|
// background horizontal scrolling registers
|
||||||
#define REG_BG0HOFS (*reinterpret_cast<volatile uint32_t*>(0x0400'0010))
|
#define REG_BG0HOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0010))
|
||||||
#define REG_BG1HOFS (*reinterpret_cast<volatile uint32_t*>(0x0400'0014))
|
#define REG_BG1HOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0014))
|
||||||
#define REG_BG2HOFS (*reinterpret_cast<volatile uint32_t*>(0x0400'0018))
|
#define REG_BG2HOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0018))
|
||||||
#define REG_BG3HOFS (*reinterpret_cast<volatile uint32_t*>(0x0400'001c))
|
#define REG_BG3HOFS (*reinterpret_cast<volatile int16_t*>(0x0400'001c))
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
volatile uint32_t ®BgHofs(auto const bgIdx) noexcept {
|
volatile int16_t ®BgHofs(auto const bgIdx) noexcept {
|
||||||
return *reinterpret_cast<volatile uint32_t*>(0x0400'0010 + 4 * bgIdx);
|
return *reinterpret_cast<volatile int16_t*>(0x0400'0010 + 4 * bgIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// background vertical scrolling registers
|
// background vertical scrolling registers
|
||||||
#define REG_BG0VOFS (*reinterpret_cast<volatile uint32_t*>(0x0400'0012))
|
#define REG_BG0VOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0012))
|
||||||
#define REG_BG1VOFS (*reinterpret_cast<volatile uint32_t*>(0x0400'0016))
|
#define REG_BG1VOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0016))
|
||||||
#define REG_BG2VOFS (*reinterpret_cast<volatile uint32_t*>(0x0400'001a))
|
#define REG_BG2VOFS (*reinterpret_cast<volatile int16_t*>(0x0400'001a))
|
||||||
#define REG_BG3VOFS (*reinterpret_cast<volatile uint32_t*>(0x0400'001e))
|
#define REG_BG3VOFS (*reinterpret_cast<volatile int16_t*>(0x0400'001e))
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
volatile uint32_t ®BgVofs(auto const bgIdx) noexcept {
|
volatile int16_t ®BgVofs(auto const bgIdx) noexcept {
|
||||||
return *reinterpret_cast<volatile uint32_t*>(0x0400'0012 + 4 * bgIdx);
|
return *reinterpret_cast<volatile int16_t*>(0x0400'0012 + 4 * bgIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// background scrolling registers
|
||||||
|
|
||||||
|
struct OffsetPair {
|
||||||
|
int16_t x{}, y{};
|
||||||
|
};
|
||||||
|
|
||||||
|
#define REG_BG0OFS (*reinterpret_cast<volatile OffsetPair*>(0x0400'0010))
|
||||||
|
#define REG_BG1OFS (*reinterpret_cast<volatile OffsetPair*>(0x0400'0014))
|
||||||
|
#define REG_BG2OFS (*reinterpret_cast<volatile OffsetPair*>(0x0400'0018))
|
||||||
|
#define REG_BG3OFS (*reinterpret_cast<volatile OffsetPair*>(0x0400'001c))
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
volatile OffsetPair ®BgOfs(auto const bgIdx) noexcept {
|
||||||
|
return *reinterpret_cast<volatile OffsetPair*>(0x0400'0010 + sizeof(OffsetPair) * bgIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
4
deps/teagba/include/teagba/gfx.hpp
vendored
4
deps/teagba/include/teagba/gfx.hpp
vendored
@@ -41,4 +41,8 @@ void addSpriteUpdate(GbaSpriteAttrUpdate const &upd) noexcept;
|
|||||||
|
|
||||||
void applySpriteUpdates() 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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
14
deps/teagba/src/gfx.cpp
vendored
14
deps/teagba/src/gfx.cpp
vendored
@@ -12,7 +12,7 @@ namespace teagba {
|
|||||||
|
|
||||||
static ox::Array<GbaSpriteAttrUpdate, 128> g_spriteBuffer;
|
static ox::Array<GbaSpriteAttrUpdate, 128> g_spriteBuffer;
|
||||||
|
|
||||||
GbaSpriteAttrUpdate &spriteAttr(size_t i) noexcept {
|
GbaSpriteAttrUpdate &spriteAttr(size_t const i) noexcept {
|
||||||
return g_spriteBuffer[i];
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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 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 hideSprite(Context &ctx, unsigned) noexcept;
|
||||||
|
|
||||||
void showSprite(Context &ctx, unsigned) noexcept;
|
void showSprite(Context &ctx, unsigned) noexcept;
|
||||||
@@ -260,8 +264,8 @@ constexpr ox::CStringView GlslVersion = "#version 330";
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ox::Size drawSize(int scale = 5) noexcept;
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -169,8 +169,8 @@ ox::Error loadBgTileSheet(
|
|||||||
unsigned const cbb,
|
unsigned const cbb,
|
||||||
CompactTileSheet const &ts,
|
CompactTileSheet const &ts,
|
||||||
ox::Optional<unsigned> const &paletteBank) noexcept {
|
ox::Optional<unsigned> const &paletteBank) noexcept {
|
||||||
auto const cnt = (ts.pixels.size() * PixelsPerTile) / (1 + (ts.bpp == 4));
|
auto const cnt = ts.pixels.size() >> (ts.bpp == 4);
|
||||||
for (size_t i = 0; i < cnt; ++i) {
|
for (size_t i{}; i < cnt; ++i) {
|
||||||
auto const srcIdx = i * 2;
|
auto const srcIdx = i * 2;
|
||||||
auto const p1 = static_cast<uint16_t>(ts.pixels[srcIdx]);
|
auto const p1 = static_cast<uint16_t>(ts.pixels[srcIdx]);
|
||||||
auto const p2 = static_cast<uint16_t>(ts.pixels[srcIdx + 1]);
|
auto const p2 = static_cast<uint16_t>(ts.pixels[srcIdx + 1]);
|
||||||
@@ -218,10 +218,11 @@ ox::Error loadSpriteTileSheet(
|
|||||||
Context &ctx,
|
Context &ctx,
|
||||||
CompactTileSheet const &ts,
|
CompactTileSheet const &ts,
|
||||||
bool const loadDefaultPalette) noexcept {
|
bool const loadDefaultPalette) noexcept {
|
||||||
for (size_t i = 0; i < ts.pixels.size(); i += 2) {
|
for (size_t i{}; i < ts.pixels.size(); i += 2) {
|
||||||
uint16_t v = ts.pixels[i];
|
MEM_SPRITE_TILES[i >> 1] =
|
||||||
v |= static_cast<uint16_t>(ts.pixels[i + 1] << 8);
|
static_cast<uint16_t>(
|
||||||
MEM_SPRITE_TILES[i] = v;
|
ts.pixels[i] |
|
||||||
|
(static_cast<uint16_t>(ts.pixels[i + 1]) << 8));
|
||||||
}
|
}
|
||||||
if (loadDefaultPalette && ts.defaultPalette) {
|
if (loadDefaultPalette && ts.defaultPalette) {
|
||||||
OX_RETURN_ERROR(loadSpritePalette(ctx, ts.defaultPalette));
|
OX_RETURN_ERROR(loadSpritePalette(ctx, ts.defaultPalette));
|
||||||
@@ -294,6 +295,14 @@ void setBgPriority(Context&, uint_t const bgIdx, uint_t const priority) noexcept
|
|||||||
bgCtl = (bgCtl & 0b1111'1111'1111'1100u) | (priority & 0b11);
|
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 {
|
void hideSprite(Context&, unsigned const idx) noexcept {
|
||||||
//oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow");
|
//oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow");
|
||||||
teagba::addSpriteUpdate({
|
teagba::addSpriteUpdate({
|
||||||
|
@@ -249,7 +249,7 @@ void setBgTile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ox::Error initConsole(Context &ctx) noexcept {
|
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");
|
constexpr ox::FileAddress PaletteAddr = ox::StringLiteral("/Palettes/Charset.npal");
|
||||||
setBgStatus(ctx, 0b0001);
|
setBgStatus(ctx, 0b0001);
|
||||||
setBgCbb(ctx, 0, 0);
|
setBgCbb(ctx, 0, 0);
|
||||||
|
@@ -19,6 +19,9 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(applib)
|
add_subdirectory(applib)
|
||||||
|
#if(NOT APPLE)
|
||||||
|
# add_subdirectory(hull)
|
||||||
|
#endif()
|
||||||
add_subdirectory(keel)
|
add_subdirectory(keel)
|
||||||
add_subdirectory(turbine)
|
add_subdirectory(turbine)
|
||||||
if(${OLYMPIC_BUILD_STUDIO})
|
if(${OLYMPIC_BUILD_STUDIO})
|
||||||
|
12
src/olympic/hull/CMakeLists.txt
Normal file
12
src/olympic/hull/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
add_library(Hull)
|
||||||
|
target_sources(
|
||||||
|
Hull PUBLIC
|
||||||
|
FILE_SET CXX_MODULES FILES
|
||||||
|
hull.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
Hull PUBLIC
|
||||||
|
OxStd
|
||||||
|
)
|
98
src/olympic/hull/hull.cpp
Normal file
98
src/olympic/hull/hull.cpp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module;
|
||||||
|
|
||||||
|
#include <ox/std/string.hpp>
|
||||||
|
|
||||||
|
export module hull;
|
||||||
|
|
||||||
|
namespace hull {
|
||||||
|
|
||||||
|
export
|
||||||
|
template<typename Str = ox::String, size_t SmallVecSz = 0>
|
||||||
|
constexpr ox::Result<ox::Vector<Str, SmallVecSz>> parseCmd(ox::StringViewCR cmd) noexcept
|
||||||
|
requires(ox::is_same_v<Str, ox::String> || ox::is_same_v<Str, ox::StringView>) {
|
||||||
|
auto const tokens = split(cmd, ' ');
|
||||||
|
ox::Vector<Str, SmallVecSz> 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<Str, ox::String>) {
|
||||||
|
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<typename Str = ox::String>
|
||||||
|
[[nodiscard]]
|
||||||
|
static constexpr bool testParse(ox::StringViewCR cmd, std::initializer_list<ox::StringView> const &expected) noexcept {
|
||||||
|
auto const [args, err] = parseCmd<Str>(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<ox::String>("echo asdf", {"echo", "asdf"}));
|
||||||
|
|
||||||
|
static_assert(testParse("echo \"asdf\"", {"echo", "asdf"}));
|
||||||
|
static_assert(testParse<ox::String>("echo \"asdf\"", {"echo", "asdf"}));
|
||||||
|
|
||||||
|
static_assert(testParse("echo 'asdf'", {"echo", "asdf"}));
|
||||||
|
static_assert(testParse<ox::String>("echo 'asdf'", {"echo", "asdf"}));
|
||||||
|
|
||||||
|
static_assert(testParse("echo 'asdf' aoue", {"echo", "asdf", "aoue"}));
|
||||||
|
static_assert(testParse<ox::String>("echo 'asdf' aoue", {"echo", "asdf", "aoue"}));
|
||||||
|
|
||||||
|
export class Prompt {
|
||||||
|
|
||||||
|
private:
|
||||||
|
ox::String m_cmd;
|
||||||
|
ox::String m_workingDir{"/"};
|
||||||
|
ox::Vector<ox::String> m_prevCmds;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user