diff --git a/deps/teagba/include/teagba/gfx.hpp b/deps/teagba/include/teagba/gfx.hpp index 8c2b6a03..530eeac7 100644 --- a/deps/teagba/include/teagba/gfx.hpp +++ b/deps/teagba/include/teagba/gfx.hpp @@ -29,13 +29,14 @@ enum DispCtl { }; struct OX_ALIGN8 GbaSpriteAttrUpdate { - uint16_t attr0 = 0; - uint16_t attr1 = 0; - uint16_t attr2 = 0; - uint16_t idx = 0; - + uint16_t attr0 = 0; + uint16_t attr1 = 0; + uint16_t attr2 = 0; + uint16_t idx = 0; }; +GbaSpriteAttrUpdate &spriteAttr(size_t i) noexcept; + void addSpriteUpdate(const GbaSpriteAttrUpdate &upd) noexcept; void applySpriteUpdates() noexcept; diff --git a/deps/teagba/src/gfx.cpp b/deps/teagba/src/gfx.cpp index 0fb2bf49..3c89bbc2 100644 --- a/deps/teagba/src/gfx.cpp +++ b/deps/teagba/src/gfx.cpp @@ -10,32 +10,23 @@ namespace teagba { -static volatile uint16_t g_spriteUpdates = 0; static ox::Array g_spriteBuffer; +GbaSpriteAttrUpdate &spriteAttr(size_t i) noexcept { + return g_spriteBuffer[i]; +} + void addSpriteUpdate(const GbaSpriteAttrUpdate &upd) noexcept { - // block until g_spriteUpdates is less than buffer len - if (g_spriteUpdates >= g_spriteBuffer.size()) [[unlikely]] { - teagba_vblankintrwait(); - } const auto ie = REG_IE; // disable vblank interrupt handler REG_IE = REG_IE & static_cast(~teagba::Int_vblank); // disable vblank interrupt handler - const auto updateCnt = g_spriteUpdates; - g_spriteBuffer[updateCnt] = upd; - g_spriteUpdates = updateCnt + 1; + g_spriteBuffer[upd.idx] = upd; REG_IE = ie; // enable vblank interrupt handler } void applySpriteUpdates() noexcept { - // copy g_spriteUpdates to allow it to use a register instead of reading - // from memory every iteration of the loop, needed because g_spriteUpdates - // is volatile - const unsigned updates = g_spriteUpdates; - for (unsigned i = 0; i < updates; ++i) { - const auto &oa = g_spriteBuffer[i]; + for (auto const&oa : g_spriteBuffer) { MEM_OAM[oa.idx] = std::bit_cast(oa); } - g_spriteUpdates = 0; } }