[teagba] Change sprite buffer to fully update on every VSync
This commit is contained in:
parent
d29118d783
commit
6de0e882e9
3
deps/teagba/include/teagba/gfx.hpp
vendored
3
deps/teagba/include/teagba/gfx.hpp
vendored
@ -33,9 +33,10 @@ struct OX_ALIGN8 GbaSpriteAttrUpdate {
|
|||||||
uint16_t attr1 = 0;
|
uint16_t attr1 = 0;
|
||||||
uint16_t attr2 = 0;
|
uint16_t attr2 = 0;
|
||||||
uint16_t idx = 0;
|
uint16_t idx = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GbaSpriteAttrUpdate &spriteAttr(size_t i) noexcept;
|
||||||
|
|
||||||
void addSpriteUpdate(const GbaSpriteAttrUpdate &upd) noexcept;
|
void addSpriteUpdate(const GbaSpriteAttrUpdate &upd) noexcept;
|
||||||
|
|
||||||
void applySpriteUpdates() noexcept;
|
void applySpriteUpdates() noexcept;
|
||||||
|
21
deps/teagba/src/gfx.cpp
vendored
21
deps/teagba/src/gfx.cpp
vendored
@ -10,32 +10,23 @@
|
|||||||
|
|
||||||
namespace teagba {
|
namespace teagba {
|
||||||
|
|
||||||
static volatile uint16_t g_spriteUpdates = 0;
|
|
||||||
static ox::Array<GbaSpriteAttrUpdate, 128> g_spriteBuffer;
|
static ox::Array<GbaSpriteAttrUpdate, 128> g_spriteBuffer;
|
||||||
|
|
||||||
void addSpriteUpdate(const GbaSpriteAttrUpdate &upd) noexcept {
|
GbaSpriteAttrUpdate &spriteAttr(size_t i) noexcept {
|
||||||
// block until g_spriteUpdates is less than buffer len
|
return g_spriteBuffer[i];
|
||||||
if (g_spriteUpdates >= g_spriteBuffer.size()) [[unlikely]] {
|
|
||||||
teagba_vblankintrwait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addSpriteUpdate(const GbaSpriteAttrUpdate &upd) noexcept {
|
||||||
const auto ie = REG_IE; // disable vblank interrupt handler
|
const auto ie = REG_IE; // disable vblank interrupt handler
|
||||||
REG_IE = REG_IE & static_cast<uint16_t>(~teagba::Int_vblank); // disable vblank interrupt handler
|
REG_IE = REG_IE & static_cast<uint16_t>(~teagba::Int_vblank); // disable vblank interrupt handler
|
||||||
const auto updateCnt = g_spriteUpdates;
|
g_spriteBuffer[upd.idx] = upd;
|
||||||
g_spriteBuffer[updateCnt] = upd;
|
|
||||||
g_spriteUpdates = updateCnt + 1;
|
|
||||||
REG_IE = ie; // enable vblank interrupt handler
|
REG_IE = ie; // enable vblank interrupt handler
|
||||||
}
|
}
|
||||||
|
|
||||||
void applySpriteUpdates() noexcept {
|
void applySpriteUpdates() noexcept {
|
||||||
// copy g_spriteUpdates to allow it to use a register instead of reading
|
for (auto const&oa : g_spriteBuffer) {
|
||||||
// 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];
|
|
||||||
MEM_OAM[oa.idx] = std::bit_cast<uint64_t>(oa);
|
MEM_OAM[oa.idx] = std::bit_cast<uint64_t>(oa);
|
||||||
}
|
}
|
||||||
g_spriteUpdates = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user