From 1bfb7f99c215e2c74556bd3281f44962b8faaa96 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Wed, 30 Jul 2025 00:40:03 -0500 Subject: [PATCH] Squashed 'deps/nostalgia/' changes from c7bc2a95..e27eee50 e27eee50 [teagba] Add set and scroll background offset functions fd610454 [nostalgia/gfx] Fix compiler warning e61d4647 [nostalgia/gfx] Fix BG tilesheet loading, add background offset functions c275c5f5 [hull] Disable building hull for now fbf49ba5 [ox/std] Add pre- and post-increment operators to Span 92f74b27 [ox/std] Add null check for deallocating in consteval context Vector 934f0c92 [ox/std] Add beginsWith and endsWith variants that that cingle chars ee9a3e11 [ox/std] Cleanup 16886cdf [hull] Add start on command interpreter 08b9508d [ox/std] Give std::ignore a named type 69bd968f [nostalgia/player] Fix build 4e7dc666 [nostalgia,olympic] Rename string len() functions to size() bea0cf5a [ox/std] Rename string len() functions to size() git-subtree-dir: deps/nostalgia git-subtree-split: e27eee50f05bb437710313430e0d9cef636a66b1 --- deps/ox/src/ox/clargs/clargs.cpp | 4 +- deps/ox/src/ox/claw/test/tests.cpp | 6 +- deps/ox/src/ox/fs/filesystem/directory.hpp | 4 +- .../ox/src/ox/fs/filesystem/passthroughfs.cpp | 2 +- deps/ox/src/ox/fs/filesystem/pathiterator.cpp | 6 +- deps/ox/src/ox/fs/test/tests.cpp | 12 +-- deps/ox/src/ox/mc/test/tests.cpp | 2 +- deps/ox/src/ox/mc/write.hpp | 10 +- deps/ox/src/ox/model/desctypes.hpp | 2 +- deps/ox/src/ox/model/typenamecatcher.hpp | 4 +- deps/ox/src/ox/oc/read.hpp | 2 +- deps/ox/src/ox/oc/write.cpp | 2 +- deps/ox/src/ox/oc/write.hpp | 4 +- deps/ox/src/ox/std/assert.cpp | 3 + deps/ox/src/ox/std/basestringview.hpp | 2 +- deps/ox/src/ox/std/cstringview.hpp | 8 +- deps/ox/src/ox/std/ignore.hpp | 2 +- deps/ox/src/ox/std/istring.hpp | 10 +- deps/ox/src/ox/std/reader.cpp | 10 +- deps/ox/src/ox/std/span.hpp | 18 ++++ deps/ox/src/ox/std/string.hpp | 40 ++++---- deps/ox/src/ox/std/stringliteral.hpp | 2 +- deps/ox/src/ox/std/stringview.hpp | 20 ++-- deps/ox/src/ox/std/strops.hpp | 48 +++++---- deps/ox/src/ox/std/test/tests.cpp | 2 +- deps/ox/src/ox/std/trace.hpp | 10 +- deps/ox/src/ox/std/uuid.hpp | 10 +- deps/ox/src/ox/std/vector.hpp | 4 +- deps/teagba/include/teagba/addresses.hpp | 40 +++++--- deps/teagba/include/teagba/gfx.hpp | 4 + deps/teagba/src/gfx.cpp | 14 ++- .../modules/gfx/include/nostalgia/gfx/gfx.hpp | 8 +- src/nostalgia/modules/gfx/src/gfx-gba.cpp | 21 ++-- src/nostalgia/modules/gfx/src/gfx.cpp | 2 +- .../export-tilesheet/export-tilesheet.cpp | 2 +- src/nostalgia/player/app.cpp | 2 +- src/olympic/CMakeLists.txt | 3 + src/olympic/applib/CMakeLists.txt | 5 + src/olympic/hull/CMakeLists.txt | 12 +++ src/olympic/hull/hull.cpp | 98 +++++++++++++++++++ src/olympic/keel/src/media.cpp | 2 +- src/olympic/keel/src/pack-applib.cpp | 2 +- src/olympic/keel/test/tests.cpp | 2 +- .../studio/applib/src/popups/newmenu.cpp | 2 +- .../studio/applib/src/projectexplorer.cpp | 2 +- .../studio/modlib/include/studio/project.hpp | 4 +- .../studio/modlib/src/filedialog_nfd.cpp | 8 +- 47 files changed, 340 insertions(+), 142 deletions(-) create mode 100644 src/olympic/hull/CMakeLists.txt create mode 100644 src/olympic/hull/hull.cpp diff --git a/deps/ox/src/ox/clargs/clargs.cpp b/deps/ox/src/ox/clargs/clargs.cpp index 854a88e..1976f25 100644 --- a/deps/ox/src/ox/clargs/clargs.cpp +++ b/deps/ox/src/ox/clargs/clargs.cpp @@ -17,14 +17,14 @@ ClArgs::ClArgs(ox::SpanView args) noexcept { for (auto i = 0u; i < args.size(); ++i) { auto arg = StringView{args[i]}; if (arg[0] == '-') { - while (arg[0] == '-' && arg.len()) { + while (arg[0] == '-' && arg.size()) { arg = substr(arg, 1); } m_bools[arg] = true; // parse additional arguments if (i < args.size() && args[i + 1]) { auto const val = StringView{args[i + 1]}; - if (val.len() && val[0] != '-') { + if (val.size() && val[0] != '-') { if (val == "false") { m_bools[arg] = false; } diff --git a/deps/ox/src/ox/claw/test/tests.cpp b/deps/ox/src/ox/claw/test/tests.cpp index a6ef919..fc6661c 100644 --- a/deps/ox/src/ox/claw/test/tests.cpp +++ b/deps/ox/src/ox/claw/test/tests.cpp @@ -109,7 +109,7 @@ static std::map tests = { "ClawHeaderReader", [] { constexpr auto hdr = ox::StringLiteral("O1;com.drinkingtea.ox.claw.test.Header;2;"); - auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.len() + 1}); + auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.size() + 1}); oxAssert(err, "Error parsing header"); oxAssert(ch.fmt == ox::ClawFormat::Organic, "Format wrong"); oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header", "Type name wrong"); @@ -121,7 +121,7 @@ static std::map tests = { "ClawHeaderReader2", [] { constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;"); - auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.len() + 1}); + auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.size() + 1}); oxAssert(err, "Error parsing header"); oxAssert(ch.fmt == ox::ClawFormat::Metal, "Format wrong"); oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header2", "Type name wrong"); @@ -134,7 +134,7 @@ static std::map tests = { [] { constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;awefawf"); constexpr auto expected = ox::StringLiteral("com.drinkingtea.ox.claw.test.Header2;3"); - OX_REQUIRE(actual, ox::readClawTypeId({hdr.data(), hdr.len() + 1})); + OX_REQUIRE(actual, ox::readClawTypeId({hdr.data(), hdr.size() + 1})); oxExpect(actual, expected); return ox::Error{}; } diff --git a/deps/ox/src/ox/fs/filesystem/directory.hpp b/deps/ox/src/ox/fs/filesystem/directory.hpp index 540ba7a..23bf6db 100644 --- a/deps/ox/src/ox/fs/filesystem/directory.hpp +++ b/deps/ox/src/ox/fs/filesystem/directory.hpp @@ -52,7 +52,7 @@ struct OX_PACKED DirectoryEntry { if (d.valid()) { d->inode = inode; auto const maxStrSz = bufferSize - 1 - sizeof(*this); - ox::strncpy(d->name, name.data(), ox::min(maxStrSz, name.len())); + ox::strncpy(d->name, name.data(), ox::min(maxStrSz, name.size())); return {}; } return ox::Error(1); @@ -219,7 +219,7 @@ Error Directory::write(PathIterator path, uint64_t inode64 oxTrace("ox.fs.Directory.write.fail", "Could not read existing version of Directory"); return ox::Error(1, "Could not read existing version of Directory"); } - const auto pathSize = name.len() + 1; + const auto pathSize = name.size() + 1; const auto entryDataSize = DirectoryEntry::DirectoryEntryData::spaceNeeded(pathSize); const auto newSize = oldStat.size + Buffer::spaceNeeded(entryDataSize); auto cpy = ox_malloca(newSize, Buffer, *old, oldStat.size); diff --git a/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp b/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp index f1f8d07..f7cab7d 100644 --- a/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp +++ b/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp @@ -206,7 +206,7 @@ Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) n } std::string_view PassThroughFS::stripSlash(StringView path) noexcept { - for (auto i = 0u; i < path.len() && path[0] == '/'; i++) { + for (auto i = 0u; i < path.size() && path[0] == '/'; i++) { path = substr(path, 1); } return {path.data(), path.bytes()}; diff --git a/deps/ox/src/ox/fs/filesystem/pathiterator.cpp b/deps/ox/src/ox/fs/filesystem/pathiterator.cpp index bd42383..39cf99a 100644 --- a/deps/ox/src/ox/fs/filesystem/pathiterator.cpp +++ b/deps/ox/src/ox/fs/filesystem/pathiterator.cpp @@ -74,7 +74,7 @@ Error PathIterator::get(StringView &fileName) { if (size && fileName[size - 1] == '/') { fileName = ox::substr(m_path, start, start + size - 1); } - oxAssert(fileName[fileName.len()-1] != '/', "name ends in /"); + oxAssert(fileName[fileName.size()-1] != '/', "name ends in /"); return {}; } @@ -104,11 +104,11 @@ Error PathIterator::next(StringView &fileName) { } fileName = ox::substr(m_path, start, start + size); // truncate trailing / - while (fileName.len() && fileName[fileName.len() - 1] == '/') { + while (fileName.size() && fileName[fileName.size() - 1] == '/') { fileName = ox::substr(m_path, start, start + size); } m_iterator += size; - oxAssert(fileName.len() == 0 || fileName[fileName.len()-1] != '/', "name ends in /"); + oxAssert(fileName.size() == 0 || fileName[fileName.size()-1] != '/', "name ends in /"); } return retval; } diff --git a/deps/ox/src/ox/fs/test/tests.cpp b/deps/ox/src/ox/fs/test/tests.cpp index dfacd24..9c69afe 100644 --- a/deps/ox/src/ox/fs/test/tests.cpp +++ b/deps/ox/src/ox/fs/test/tests.cpp @@ -59,7 +59,7 @@ const std::map> tests = "PathIterator::next1", [](ox::StringView) { auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag"); - ox::PathIterator it(path.c_str(), path.len()); + ox::PathIterator it(path.c_str(), path.size()); ox::StringView buff; oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next"); oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next"); @@ -84,7 +84,7 @@ const std::map> tests = "PathIterator::next3", [](ox::StringView) { auto const path = ox::String("/"); - ox::PathIterator it(path.c_str(), path.len()); + ox::PathIterator it(path.c_str(), path.size()); ox::StringView buff; oxAssert(it.next(buff) == 0 && buff == "\0", "PathIterator shows wrong next"); return ox::Error(0); @@ -106,7 +106,7 @@ const std::map> tests = "PathIterator::next5", [](ox::StringView) { auto const path = ox::String("usr/share/"); - ox::PathIterator it(path.c_str(), path.len()); + ox::PathIterator it(path.c_str(), path.size()); ox::StringView buff; oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next"); oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next"); @@ -117,10 +117,10 @@ const std::map> tests = "PathIterator::dirPath", [] (ox::StringView) { auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag"); - ox::PathIterator it(path.c_str(), path.len()); - auto buff = static_cast(ox_alloca(path.len() + 1)); + ox::PathIterator it(path.c_str(), path.size()); + auto buff = static_cast(ox_alloca(path.size() + 1)); OX_ALLOW_UNSAFE_BUFFERS_BEGIN - oxAssert(it.dirPath(buff, path.len()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path"); + oxAssert(it.dirPath(buff, path.size()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path"); OX_ALLOW_UNSAFE_BUFFERS_END return ox::Error(0); } diff --git a/deps/ox/src/ox/mc/test/tests.cpp b/deps/ox/src/ox/mc/test/tests.cpp index 180d8ef..8d5a46d 100644 --- a/deps/ox/src/ox/mc/test/tests.cpp +++ b/deps/ox/src/ox/mc/test/tests.cpp @@ -157,7 +157,7 @@ std::map tests = { oxAssert(testIn.Int8 == testOut.Int8, "Int8 value mismatch"); oxAssert(testIn.Union.Int == testOut.Union.Int, "Union.Int value mismatch"); oxAssert(testIn.String == testOut.String, "String value mismatch"); - oxDebugf("{}", testOut.IString.len()); + oxDebugf("{}", testOut.IString.size()); oxExpect(testIn.IString, testOut.IString); oxAssert(testIn.List[0] == testOut.List[0], "List[0] value mismatch"); oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch"); diff --git a/deps/ox/src/ox/mc/write.hpp b/deps/ox/src/ox/mc/write.hpp index dfab98c..4c836ff 100644 --- a/deps/ox/src/ox/mc/write.hpp +++ b/deps/ox/src/ox/mc/write.hpp @@ -191,12 +191,12 @@ template template constexpr Error MetalClawWriter::field(const char*, const BasicString *val) noexcept { bool fieldSet = false; - if (val->len() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { + if (val->size() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { // write the length - const auto strLen = mc::encodeInteger(val->len()); + const auto strLen = mc::encodeInteger(val->size()); OX_RETURN_ERROR(m_writer.write(reinterpret_cast(strLen.data.data()), strLen.length)); // write the string - OX_RETURN_ERROR(m_writer.write(val->c_str(), static_cast(val->len()))); + OX_RETURN_ERROR(m_writer.write(val->c_str(), static_cast(val->size()))); fieldSet = true; } OX_RETURN_ERROR(m_fieldPresence.set(static_cast(m_field), fieldSet)); @@ -207,7 +207,7 @@ constexpr Error MetalClawWriter::field(const char*, const BasicString template constexpr Error MetalClawWriter::field(const char *name, const IString *val) noexcept { - return fieldCString(name, val->data(), val->len()); + return fieldCString(name, val->data(), val->size()); } template @@ -339,7 +339,7 @@ constexpr Error MetalClawWriter::field(const char*, const HashMap ox::Error { - const auto keyLen = key.len(); + const auto keyLen = key.size(); auto wkey = ox_malloca(keyLen + 1, char, 0); memcpy(wkey.get(), key.c_str(), keyLen + 1); OX_RETURN_ERROR(handler.fieldCString("", wkey.get(), keyLen)); diff --git a/deps/ox/src/ox/model/desctypes.hpp b/deps/ox/src/ox/model/desctypes.hpp index 4bbb736..b436416 100644 --- a/deps/ox/src/ox/model/desctypes.hpp +++ b/deps/ox/src/ox/model/desctypes.hpp @@ -43,7 +43,7 @@ static constexpr auto buildTypeId( for (const auto &p : typeParams) { tp += p + ","; } - tp.resize(tp.len() - 1); + tp.resize(tp.size() - 1); tp += "#"; } return ox::sfmt("{}{};{}", name, tp, version); diff --git a/deps/ox/src/ox/model/typenamecatcher.hpp b/deps/ox/src/ox/model/typenamecatcher.hpp index 418a2e0..4c5cd77 100644 --- a/deps/ox/src/ox/model/typenamecatcher.hpp +++ b/deps/ox/src/ox/model/typenamecatcher.hpp @@ -144,7 +144,7 @@ template [[nodiscard]] consteval auto requireModelTypeName() noexcept { constexpr auto name = getModelTypeName(); - static_assert(ox::StringView{name}.len(), "Type lacks required TypeName"); + static_assert(ox::StringView{name}.size(), "Type lacks required TypeName"); return name; } @@ -159,7 +159,7 @@ constexpr auto ModelTypeId_v = [] { constexpr auto name = ModelTypeName_v; constexpr auto version = ModelTypeVersion_v; constexpr auto versionStr = ox::sfmt>("{}", version); - return ox::sfmt>("{};{}", name, versionStr); + return ox::sfmt>("{};{}", name, versionStr); }(); } diff --git a/deps/ox/src/ox/oc/read.hpp b/deps/ox/src/ox/oc/read.hpp index 60593ac..81a12cd 100644 --- a/deps/ox/src/ox/oc/read.hpp +++ b/deps/ox/src/ox/oc/read.hpp @@ -307,7 +307,7 @@ Result readOC(BufferView buff) noexcept { template Result readOC(ox::StringView json) noexcept { - return readOC(ox::BufferView{json.data(), json.len()}); + return readOC(ox::BufferView{json.data(), json.size()}); } } diff --git a/deps/ox/src/ox/oc/write.cpp b/deps/ox/src/ox/oc/write.cpp index 392cbf4..3e27a03 100644 --- a/deps/ox/src/ox/oc/write.cpp +++ b/deps/ox/src/ox/oc/write.cpp @@ -32,7 +32,7 @@ Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) no Error OrganicClawWriter::field(const char *key, const UUID *uuid) noexcept { const auto uuidStr = uuid->toString(); - if (targetValid() && uuidStr.len()) { + if (targetValid() && uuidStr.size()) { value(key) = uuidStr.c_str(); } ++m_fieldIt; diff --git a/deps/ox/src/ox/oc/write.hpp b/deps/ox/src/ox/oc/write.hpp index f7358c1..b8ca98e 100644 --- a/deps/ox/src/ox/oc/write.hpp +++ b/deps/ox/src/ox/oc/write.hpp @@ -138,7 +138,7 @@ class OrganicClawWriter { template Error field(char const*key, IString const*val) noexcept { - if (targetValid() && val->len()) { + if (targetValid() && val->size()) { value(key) = val->c_str(); } ++m_fieldIt; @@ -147,7 +147,7 @@ class OrganicClawWriter { template Error field(char const*key, BasicString const*val) noexcept { - if (targetValid() && val->len()) { + if (targetValid() && val->size()) { value(key) = val->c_str(); } ++m_fieldIt; diff --git a/deps/ox/src/ox/std/assert.cpp b/deps/ox/src/ox/std/assert.cpp index aacd0f7..5384351 100644 --- a/deps/ox/src/ox/std/assert.cpp +++ b/deps/ox/src/ox/std/assert.cpp @@ -33,6 +33,9 @@ void panic(StringViewCR file, int const line, StringViewCR panicMsg, Error const #endif } +#if __GNUC__ +__attribute__((weak)) +#endif void panic(const char *file, int const line, char const*panicMsg, Error const&err) noexcept { panic(StringView{file}, line, StringView{panicMsg}, err); } diff --git a/deps/ox/src/ox/std/basestringview.hpp b/deps/ox/src/ox/std/basestringview.hpp index 3d50cc9..92b68a7 100644 --- a/deps/ox/src/ox/std/basestringview.hpp +++ b/deps/ox/src/ox/std/basestringview.hpp @@ -185,7 +185,7 @@ class BaseStringView { } [[nodiscard]] - constexpr auto len() const noexcept { + constexpr auto size() const noexcept { return m_len; } diff --git a/deps/ox/src/ox/std/cstringview.hpp b/deps/ox/src/ox/std/cstringview.hpp index d356f2b..f37c23a 100644 --- a/deps/ox/src/ox/std/cstringview.hpp +++ b/deps/ox/src/ox/std/cstringview.hpp @@ -21,13 +21,13 @@ class CStringView: public detail::BaseStringView { constexpr CStringView(CStringView const&sv) noexcept = default; - constexpr CStringView(StringLiteral const&str) noexcept: BaseStringView(str.data(), str.len()) {} + constexpr CStringView(StringLiteral const&str) noexcept: BaseStringView(str.data(), str.size()) {} template - constexpr CStringView(BasicString const&str) noexcept: BaseStringView(str.data(), str.len()) {} + constexpr CStringView(BasicString const&str) noexcept: BaseStringView(str.data(), str.size()) {} template - constexpr CStringView(IString const&str) noexcept: BaseStringView(str.data(), str.len()) {} + constexpr CStringView(IString const&str) noexcept: BaseStringView(str.data(), str.size()) {} constexpr CStringView(std::nullptr_t) noexcept {} @@ -37,7 +37,7 @@ class CStringView: public detail::BaseStringView { constexpr auto &operator=(CStringView const&other) noexcept { if (&other != this) { - set(other.data(), other.len()); + set(other.data(), other.size()); } return *this; } diff --git a/deps/ox/src/ox/std/ignore.hpp b/deps/ox/src/ox/std/ignore.hpp index 5dcaa5c..52fc425 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; diff --git a/deps/ox/src/ox/std/istring.hpp b/deps/ox/src/ox/std/istring.hpp index 3ba1c9b..a21a586 100644 --- a/deps/ox/src/ox/std/istring.hpp +++ b/deps/ox/src/ox/std/istring.hpp @@ -72,7 +72,7 @@ class IString { * Returns the number of characters in this string. */ [[nodiscard]] - constexpr std::size_t len() const noexcept; + constexpr std::size_t size() const noexcept; /** * Returns the number of bytes used for this string. @@ -121,7 +121,7 @@ constexpr IString &IString::operator=(Integer_c auto i) noexcept { template constexpr IString &IString::operator=(ox::StringViewCR str) noexcept { - std::size_t strLen = str.len(); + std::size_t strLen = str.size(); if (cap() < strLen) { strLen = cap(); } @@ -171,7 +171,7 @@ constexpr char &IString::operator[](std::size_t i) noexcept { template constexpr Error IString::append(const char *str, std::size_t strLen) noexcept { Error err{}; - auto const currentLen = len(); + auto const currentLen = size(); if (cap() < currentLen + strLen) { strLen = cap() - currentLen; err = ox::Error(1, "Insufficient space for full string"); @@ -187,7 +187,7 @@ OX_CLANG_NOWARN_END template constexpr Error IString::append(ox::StringView str) noexcept { - return append(str.data(), str.len()); + return append(str.data(), str.size()); } template @@ -207,7 +207,7 @@ constexpr const char *IString::c_str() const noexcept { template -constexpr std::size_t IString::len() const noexcept { +constexpr std::size_t IString::size() const noexcept { return m_size; } diff --git a/deps/ox/src/ox/std/reader.cpp b/deps/ox/src/ox/std/reader.cpp index b29c4b5..13acc66 100644 --- a/deps/ox/src/ox/std/reader.cpp +++ b/deps/ox/src/ox/std/reader.cpp @@ -30,13 +30,15 @@ constexpr std::ios_base::seekdir sdMap(ox::ios_base::seekdir in) noexcept { ox::Result StreamReader::peek() const noexcept { try { + if (m_strm.eof()) { + return Error{1, "EOF"}; + } char c{}; m_strm.get(c); - auto const ok = c != EOF; - if (ok && m_strm.unget()) [[unlikely]] { - return ox::Error(1, "Unable to unget character"); + if (m_strm.unget()) [[unlikely]] { + return ox::Error{1, "Unable to unget character"}; } - return {static_cast(c), ox::Error(!ok, "File peek failed")}; + return static_cast(c); } catch (std::exception const&) { return ox::Error(1, "peek failed"); } diff --git a/deps/ox/src/ox/std/span.hpp b/deps/ox/src/ox/std/span.hpp index 871dd88..381e83e 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; diff --git a/deps/ox/src/ox/std/string.hpp b/deps/ox/src/ox/std/string.hpp index 615e621..d31f58b 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; @@ -176,7 +176,7 @@ class BasicString { constexpr char &operator[](std::size_t i) noexcept; constexpr Error append(const char *str, std::size_t strLen) noexcept { - auto currentLen = len(); + auto currentLen = size(); m_buff.resize(m_buff.size() + strLen); ox::listcpy(&m_buff[currentLen], str, strLen); // make sure last element is a null terminator @@ -185,8 +185,8 @@ class BasicString { return {}; } - constexpr Error append(ox::StringView sv) noexcept { - return append(sv.data(), sv.len()); + constexpr Error append(StringViewCR sv) noexcept { + return append(sv.data(), sv.size()); } [[nodiscard]] @@ -237,7 +237,7 @@ class BasicString { * Returns the number of characters in this string. */ [[nodiscard]] - constexpr std::size_t len() const noexcept; + constexpr std::size_t size() const noexcept; /** * Returns the number of bytes used for this string. @@ -277,7 +277,7 @@ constexpr BasicString::BasicString(const char *str, std::size template constexpr BasicString::BasicString(StringLiteral const&str) noexcept: - BasicString(StringView{str.data(), str.len()}) { + BasicString(StringView{str.data(), str.size()}) { } template @@ -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; @@ -384,14 +384,14 @@ constexpr BasicString &BasicString::operat template constexpr BasicString &BasicString::operator+=(BasicString const&src) noexcept { - std::ignore = append(src.c_str(), src.len()); + std::ignore = append(src.c_str(), src.size()); return *this; } template constexpr BasicString BasicString::operator+(const char *str) const noexcept { const std::size_t strLen = ox::strlen(str); - const auto currentLen = len(); + const auto currentLen = size(); BasicString cpy; cpy.m_buff.resize(m_buff.size() + strLen); ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen); @@ -420,8 +420,8 @@ constexpr BasicString BasicString::operato template constexpr BasicString BasicString::operator+(StringViewCR src) const noexcept { - const std::size_t strLen = src.len(); - const auto currentLen = len(); + const std::size_t strLen = src.size(); + const auto currentLen = size(); BasicString cpy(currentLen + strLen); cpy.m_buff.resize(m_buff.size() + strLen); ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen); @@ -432,8 +432,8 @@ constexpr BasicString BasicString::operato template constexpr BasicString BasicString::operator+(BasicString const&src) const noexcept { - const std::size_t strLen = src.len(); - const auto currentLen = len(); + const std::size_t strLen = src.size(); + const auto currentLen = size(); BasicString cpy(currentLen + strLen); cpy.m_buff.resize(m_buff.size() + strLen); ox::listcpy(&cpy.m_buff[0], m_buff.data(), currentLen); @@ -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 @@ -521,7 +521,7 @@ constexpr std::size_t BasicString::bytes() const noexcept { } template -constexpr std::size_t BasicString::len() const noexcept { +constexpr std::size_t BasicString::size() const noexcept { return m_buff.size() - 1; } @@ -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; }; } diff --git a/deps/ox/src/ox/std/stringliteral.hpp b/deps/ox/src/ox/std/stringliteral.hpp index ec5d463..f78b946 100644 --- a/deps/ox/src/ox/std/stringliteral.hpp +++ b/deps/ox/src/ox/std/stringliteral.hpp @@ -32,7 +32,7 @@ class StringLiteral: public detail::BaseStringView { OX_ALLOW_UNSAFE_BUFFERS_END constexpr StringLiteral &operator=(StringLiteral const &other) noexcept { - set(other.data(), other.len()); + set(other.data(), other.size()); return *this; } diff --git a/deps/ox/src/ox/std/stringview.hpp b/deps/ox/src/ox/std/stringview.hpp index 6fc955c..0b8b24c 100644 --- a/deps/ox/src/ox/std/stringview.hpp +++ b/deps/ox/src/ox/std/stringview.hpp @@ -40,10 +40,10 @@ class StringView: public detail::BaseStringView { constexpr StringView(BaseStringView const&str) noexcept: BaseStringView(str.data(), str.bytes()) {} template - constexpr StringView(const BasicString &str) noexcept: BaseStringView(str.data(), str.len()) {} + constexpr StringView(const BasicString &str) noexcept: BaseStringView(str.data(), str.size()) {} template - constexpr StringView(const IString &str) noexcept: BaseStringView(str.data(), str.len()) {} + constexpr StringView(const IString &str) noexcept: BaseStringView(str.data(), str.size()) {} constexpr StringView(std::nullptr_t) noexcept {} @@ -53,7 +53,7 @@ class StringView: public detail::BaseStringView { constexpr auto &operator=(StringView const&other) noexcept { if (&other != this) { - set(other.data(), other.len()); + set(other.data(), other.size()); } return *this; } @@ -63,14 +63,14 @@ class StringView: public detail::BaseStringView { using StringViewCR = StringView const&; constexpr auto operator==(StringViewCR s1, StringViewCR s2) noexcept { - if (s2.len() != s1.len()) { + if (s2.size() != s1.size()) { return false; } - return ox::strncmp(s1.data(), s2.data(), s1.len()) == 0; + return ox::strncmp(s1.data(), s2.data(), s1.size()) == 0; } constexpr auto operator<=>(StringViewCR s1, StringViewCR s2) noexcept { - const auto maxLen = ox::min(s1.len(), s2.len()); + const auto maxLen = ox::min(s1.size(), s2.size()); const auto a = &s1.front(); const auto b = &s2.front(); for (std::size_t i = 0; i < maxLen && (a[i] || b[i]); ++i) { @@ -80,9 +80,9 @@ constexpr auto operator<=>(StringViewCR s1, StringViewCR s2) noexcept { return 1; } } - if (s1.len() > s2.len()) { + if (s1.size() > s2.size()) { return 1; - } else if (s1.len() < s2.len()) { + } else if (s1.size() < s2.size()) { return -1; } else { return 0; @@ -104,10 +104,10 @@ constexpr ox::Result strToInt(StringViewCR str) noexcept { OX_ALLOW_UNSAFE_BUFFERS_BEGIN int total = 0; int multiplier = 1; - if (str.len() == 0) [[unlikely]] { + if (str.size() == 0) [[unlikely]] { return Error{1, "Empty string passed to strToInt"}; } - for (auto i = static_cast(str.len()) - 1; i != -1; --i) { + for (auto i = static_cast(str.size()) - 1; i != -1; --i) { auto s = static_cast(i); if (str[s] >= '0' && str[s] <= '9') { total += (str[s] - '0') * multiplier; diff --git a/deps/ox/src/ox/std/strops.hpp b/deps/ox/src/ox/std/strops.hpp index db85d4c..86251f4 100644 --- a/deps/ox/src/ox/std/strops.hpp +++ b/deps/ox/src/ox/std/strops.hpp @@ -21,37 +21,47 @@ OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage) namespace ox { [[nodiscard]] -constexpr ox::StringView substr(ox::StringView const&str, std::size_t pos) noexcept { - if (str.len() >= pos) { - return {&str[pos], str.len() - pos}; +constexpr StringView substr(StringViewCR str, std::size_t const pos) noexcept { + if (str.size() >= pos) { + return {&str[pos], str.size() - pos}; } return {}; } [[nodiscard]] -constexpr ox::StringView substr(ox::StringView const&str, std::size_t start, std::size_t end) noexcept { - if (str.len() >= start && end >= start) { +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.len(), base.len()); - return base.len() >= beginning.len() && ox::strncmp(base.data(), beginning, beginningLen) == 0; + const auto beginningLen = ox::min(beginning.size(), base.size()); + return base.size() >= beginning.size() && ox::strncmp(base.data(), beginning, beginningLen) == 0; } [[nodiscard]] constexpr bool endsWith(StringViewCR base, StringViewCR ending) noexcept { - const auto endingLen = ending.len(); - return base.len() >= endingLen && ox::strcmp(base.data() + (base.len() - endingLen), ending) == 0; + const auto endingLen = ending.size(); + return base.size() >= endingLen && ox::strcmp(base.data() + (base.size() - endingLen), ending) == 0; } [[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.len(); ++i) { + for (; i < str.size(); ++i) { if (str[i] == search) { break; } @@ -62,7 +72,7 @@ constexpr std::size_t find(StringViewCR str, char search) noexcept { [[nodiscard]] constexpr std::size_t find(StringViewCR str, StringViewCR search) noexcept { std::size_t i = 0; - for (; i < str.len(); ++i) { + for (; i < str.size(); ++i) { if (beginsWith(substr(str, i), search)) { break; } @@ -72,14 +82,14 @@ 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); }; - for (auto current = str; current.len(); current = nextSeg(current, del)) { + for (auto current = str; current.size(); current = nextSeg(current, del)) { const auto next = find(current, del); - if (const auto s = substr(current, 0, next); s.len()) { + if (const auto s = substr(current, 0, next); s.size()) { out.emplace_back(s); } current = substr(current, next); @@ -92,11 +102,11 @@ template constexpr ox::Vector split(StringViewCR str, StringViewCR del) noexcept { ox::Vector out; constexpr auto nextSeg = [](StringViewCR current, StringViewCR del) { - return substr(current, find(current, del) + del.len()); + return substr(current, find(current, del) + del.size()); }; - for (auto current = str; current.len(); current = nextSeg(current, del)) { + for (auto current = str; current.size(); current = nextSeg(current, del)) { const auto next = find(current, del); - if (const auto s = substr(current, 0, next); s.len()) { + if (const auto s = substr(current, 0, next); s.size()) { out.emplace_back(s); } current = substr(current, next); @@ -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) { diff --git a/deps/ox/src/ox/std/test/tests.cpp b/deps/ox/src/ox/std/test/tests.cpp index 7707199..b44c6b7 100644 --- a/deps/ox/src/ox/std/test/tests.cpp +++ b/deps/ox/src/ox/std/test/tests.cpp @@ -183,7 +183,7 @@ OX_CLANG_NOWARN_END s = "asdf"; oxAssert(s == "asdf", "String assign broken"); oxAssert(s != "aoeu", "String assign broken"); - oxAssert(s.len() == 4, "String assign broken"); + oxAssert(s.size() == 4, "String assign broken"); return ox::Error(0); } }, diff --git a/deps/ox/src/ox/std/trace.hpp b/deps/ox/src/ox/std/trace.hpp index c33cf82..7dbaaea 100644 --- a/deps/ox/src/ox/std/trace.hpp +++ b/deps/ox/src/ox/std/trace.hpp @@ -166,7 +166,7 @@ class OutStream { constexpr OutStream &operator<<(Integer_c auto v) noexcept; constexpr OutStream &operator<<(char v) noexcept { - if (m_msg.msg.len()) { + if (m_msg.msg.size()) { m_msg.msg += m_delimiter; } m_msg.msg += v; @@ -174,7 +174,7 @@ class OutStream { } constexpr OutStream &operator<<(StringViewCR v) noexcept { - if (m_msg.msg.len()) { + if (m_msg.msg.size()) { m_msg.msg += m_delimiter; } m_msg.msg += v; @@ -209,7 +209,7 @@ class OutStream { private: constexpr OutStream &appendSignedInt(int64_t v) noexcept { - if (m_msg.msg.len()) { + if (m_msg.msg.size()) { m_msg.msg += m_delimiter; } m_msg.msg += static_cast(v); @@ -217,7 +217,7 @@ class OutStream { } constexpr OutStream &appendUnsignedInt(uint64_t v) noexcept { - if (m_msg.msg.len()) { + if (m_msg.msg.size()) { m_msg.msg += m_delimiter; } m_msg.msg += static_cast(v); @@ -227,7 +227,7 @@ class OutStream { }; constexpr OutStream &OutStream::operator<<(Integer_c auto v) noexcept { - if (m_msg.msg.len()) { + if (m_msg.msg.size()) { m_msg.msg += m_delimiter; } m_msg.msg += v; diff --git a/deps/ox/src/ox/std/uuid.hpp b/deps/ox/src/ox/std/uuid.hpp index 76bd136..325cf0c 100644 --- a/deps/ox/src/ox/std/uuid.hpp +++ b/deps/ox/src/ox/std/uuid.hpp @@ -58,7 +58,7 @@ constexpr ox::Result fromHex(ox::StringViewCR v) noexcept { if (!detail::isHexChar(v[0]) || !detail::isHexChar(v[1])) { return ox::Error(1, "Invalid UUID"); } - if (v.len() != 2) { + if (v.size() != 2) { return ox::Error(2); } uint8_t out = 0; @@ -133,18 +133,18 @@ class UUID { } static constexpr ox::Result fromString(ox::StringViewCR s) noexcept { - if (s.len() < 36) { + if (s.size() < 36) { return ox::Error(1, "Insufficient data to contain a complete UUID"); } UUID out; auto valueI = 0u; - for (size_t i = 0; i < s.len();) { + for (size_t i = 0; i < s.size();) { if (s[i] == '-') { ++i; continue; } const auto seg = substr(s, i, i + 2); - if (seg.len() != 2) { + if (seg.size() != 2) { return ox::Error(1, "Invalid UUID"); } OX_REQUIRE(val, detail::fromHex(seg)); @@ -174,7 +174,7 @@ class UUID { for (auto i = 0u; i < cnt; ++i) { const auto v = value[valueI]; const auto h = detail::toHex(v); - std::ignore = writer.write(h.c_str(), h.len()); + std::ignore = writer.write(h.c_str(), h.size()); ++valueI; } }; diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index faab065..aa57062 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); diff --git a/deps/teagba/include/teagba/addresses.hpp b/deps/teagba/include/teagba/addresses.hpp index 23380b1..6b2e5e2 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 bd18bb3..4a25212 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 b458eef..cd1e38b 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; +} + } diff --git a/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp b/src/nostalgia/modules/gfx/include/nostalgia/gfx/gfx.hpp index 978c0a9..792bd82 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 ad67b35..a1d6ba4 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,11 @@ 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 +295,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 e52ac87..4c93a2c 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); diff --git a/src/nostalgia/modules/gfx/src/studio/subcommands/export-tilesheet/export-tilesheet.cpp b/src/nostalgia/modules/gfx/src/studio/subcommands/export-tilesheet/export-tilesheet.cpp index 31c0ce3..1f26e24 100644 --- a/src/nostalgia/modules/gfx/src/studio/subcommands/export-tilesheet/export-tilesheet.cpp +++ b/src/nostalgia/modules/gfx/src/studio/subcommands/export-tilesheet/export-tilesheet.cpp @@ -146,7 +146,7 @@ ox::Error cmdExportTilesheet(studio::Project &project, ox::SpanView // load objects auto &kctx = project.kctx(); OX_REQUIRE(ts, keel::readObj(kctx, srcPath).transformError(4, "could not load TileSheet")); - OX_REQUIRE(pal, keel::readObj(kctx, palPath.len() ? palPath : ts->defaultPalette) + OX_REQUIRE(pal, keel::readObj(kctx, palPath.size() ? palPath : ts->defaultPalette) .transformError(5, "could not load Palette")); // export to the destination file return exportSubsheetToPng( diff --git a/src/nostalgia/player/app.cpp b/src/nostalgia/player/app.cpp index aeddbed..f91a171 100644 --- a/src/nostalgia/player/app.cpp +++ b/src/nostalgia/player/app.cpp @@ -38,7 +38,7 @@ static int testUpdateHandler(turbine::Context &tctx) noexcept { spriteX += xmod; spriteY += ymod; constexpr ox::StringView sprites = "nostalgia"; - for (unsigned i = 0; i < sprites.len(); ++i) { + for (unsigned i = 0; i < sprites.size(); ++i) { auto const c = static_cast(sprites[i] - ('a' - 1)); gfx::setSprite(cctx, i, { .enabled = true, diff --git a/src/olympic/CMakeLists.txt b/src/olympic/CMakeLists.txt index f054cda..a415516 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/applib/CMakeLists.txt b/src/olympic/applib/CMakeLists.txt index 0b20b16..ef01a00 100644 --- a/src/olympic/applib/CMakeLists.txt +++ b/src/olympic/applib/CMakeLists.txt @@ -3,6 +3,11 @@ add_library( OlympicApplib INTERFACE ) +target_link_libraries( + OlympicApplib INTERFACE + OxLogConn +) + target_sources( OlympicApplib INTERFACE applib.cpp diff --git a/src/olympic/hull/CMakeLists.txt b/src/olympic/hull/CMakeLists.txt new file mode 100644 index 0000000..5fc56b0 --- /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 0000000..9a9d7ca --- /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: + +}; + +} diff --git a/src/olympic/keel/src/media.cpp b/src/olympic/keel/src/media.cpp index 0c5b831..8dba38f 100644 --- a/src/olympic/keel/src/media.cpp +++ b/src/olympic/keel/src/media.cpp @@ -59,7 +59,7 @@ static ox::Error buildUuidMap(Context &ctx, ox::StringViewCR path, DuplicateSet auto const [uuid, err] = readUuidHeader(buff); if (!err) { // check for duplication - if (duplicates && ctx.uuidToPath[uuid.toString()].len()) { + if (duplicates && ctx.uuidToPath[uuid.toString()].size()) { auto &dl = (*duplicates)[uuid]; if (dl.empty()) { dl.emplace_back(ctx.uuidToPath[uuid.toString()]); diff --git a/src/olympic/keel/src/pack-applib.cpp b/src/olympic/keel/src/pack-applib.cpp index 5222e03..953230b 100644 --- a/src/olympic/keel/src/pack-applib.cpp +++ b/src/olympic/keel/src/pack-applib.cpp @@ -88,7 +88,7 @@ static ox::Error pack( oxOutf("Final ROM buff size: {} bytes\n", romBuff.size()); OX_RETURN_ERROR(writeFileBuff(argRomBin, romBuff)); OX_REQUIRE(manifestJson, ox::writeOCString(manifest)); - OX_RETURN_ERROR(writeFileBuff(argManifest, {manifestJson.data(), manifestJson.len()})); + OX_RETURN_ERROR(writeFileBuff(argManifest, {manifestJson.data(), manifestJson.size()})); return {}; } diff --git a/src/olympic/keel/test/tests.cpp b/src/olympic/keel/test/tests.cpp index 5e18e39..e78280d 100644 --- a/src/olympic/keel/test/tests.cpp +++ b/src/olympic/keel/test/tests.cpp @@ -16,7 +16,7 @@ static std::map tests = { constexpr ox::StringView uuidStr = "8d814442-f46e-4cc3-8edc-ca3c01cc86db"; constexpr ox::StringView hdr = "K1;8d814442-f46e-4cc3-8edc-ca3c01cc86db;"; OX_REQUIRE(uuid, ox::UUID::fromString(uuidStr)); - ox::Array buff; + ox::Array buff; ox::CharBuffWriter bw(buff); OX_RETURN_ERROR(keel::writeUuidHeader(bw, uuid)); oxExpect(ox::StringView(buff.data(), buff.size()), hdr); diff --git a/src/olympic/studio/applib/src/popups/newmenu.cpp b/src/olympic/studio/applib/src/popups/newmenu.cpp index ded8fd7..9e6d68d 100644 --- a/src/olympic/studio/applib/src/popups/newmenu.cpp +++ b/src/olympic/studio/applib/src/popups/newmenu.cpp @@ -192,7 +192,7 @@ void NewMenu::drawLastPageButtons(Context &sctx) noexcept { } void NewMenu::finish(Context &sctx) noexcept { - if (m_itemName.len() == 0) { + if (m_itemName.size() == 0) { oxLogError(ox::Error{1, "New file error: no file name"}); return; } diff --git a/src/olympic/studio/applib/src/projectexplorer.cpp b/src/olympic/studio/applib/src/projectexplorer.cpp index d3b374d..6eb9074 100644 --- a/src/olympic/studio/applib/src/projectexplorer.cpp +++ b/src/olympic/studio/applib/src/projectexplorer.cpp @@ -57,7 +57,7 @@ void ProjectExplorer::dirContextMenu(ox::StringViewCR path) const noexcept { if (ImGui::MenuItem("Add Directory")) { addDir.emit(path); } - if (path.len() && ImGui::MenuItem("Delete")) { + if (path.size() && ImGui::MenuItem("Delete")) { deleteItem.emit(path); } ImGui::EndPopup(); diff --git a/src/olympic/studio/modlib/include/studio/project.hpp b/src/olympic/studio/modlib/include/studio/project.hpp index f730e8b..6d9bd27 100644 --- a/src/olympic/studio/modlib/include/studio/project.hpp +++ b/src/olympic/studio/modlib/include/studio/project.hpp @@ -40,8 +40,8 @@ constexpr ox::Result fileExt(ox::StringViewCR path) noexcept { [[nodiscard]] constexpr ox::StringView parentDir(ox::StringView path) noexcept { - if (path.len() && path[path.len() - 1] == '/') { - path = substr(path, 0, path.len() - 1); + if (path.size() && path[path.size() - 1] == '/') { + path = substr(path, 0, path.size() - 1); } auto const extStart = ox::find(path.crbegin(), path.crend(), '/').offset(); return substr(path, 0, extStart); diff --git a/src/olympic/studio/modlib/src/filedialog_nfd.cpp b/src/olympic/studio/modlib/src/filedialog_nfd.cpp index f298621..2d35b60 100644 --- a/src/olympic/studio/modlib/src/filedialog_nfd.cpp +++ b/src/olympic/studio/modlib/src/filedialog_nfd.cpp @@ -13,10 +13,10 @@ namespace studio { FDFilterItem::FDFilterItem(ox::StringViewCR pName, ox::StringViewCR pSpec) noexcept { OX_ALLOW_UNSAFE_BUFFERS_BEGIN - name.resize(pName.len() + 1); - ox::strncpy(name.data(), pName.data(), pName.len()); - spec.resize(pSpec.len() + 1); - ox::strncpy(spec.data(), pSpec.data(), pSpec.len()); + name.resize(pName.size() + 1); + ox::strncpy(name.data(), pName.data(), pName.size()); + spec.resize(pSpec.size() + 1); + ox::strncpy(spec.data(), pSpec.data(), pSpec.size()); OX_ALLOW_UNSAFE_BUFFERS_END }