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