#include "egg/core/eggXfbManager.h" #include "common.h" #include "egg/core/eggXfb.h" #include "nw4r/db/db_directPrint.h" #include "rvl/VI.h" // IWYU pragma: export namespace EGG { bool XfbManager::isRegisterd(Xfb &xfb) const { Xfb *x = mNextXfb; Xfb *iter = x; if (mNextXfb != nullptr) { do { if (iter == &xfb) { return true; } iter = iter->mNext; } while (iter != x); } return false; } bool XfbManager::attach(Xfb *xfb) { int interrupts = OSDisableInterrupts(); bool u3 = 0; if (xfb != nullptr && !isRegisterd(*xfb)) { xfb->mState = Xfb::XFB_UNPROCESSED; if (mNextXfb == nullptr) { mNextXfb = xfb; mToCopyXfb = xfb; xfb->mNext = xfb; xfb->mPrev = xfb; } else { mNextXfb->mPrev->mNext = xfb; xfb->mPrev = mNextXfb->mPrev; mNextXfb->mPrev = xfb; xfb->mNext = mNextXfb; } u3 = 1; mNumXfbs += 1; mNumXfbs_Copy += 1; } OSRestoreInterrupts(interrupts); return u3; } void XfbManager::copyEFB(bool bUpdate) { if (mNumXfbs == 1 && mToCopyXfb == nullptr) { mToCopyXfb = mNextXfb; } if (mToCopyXfb != nullptr) { if (bUpdate) { GXSetZMode(true, GX_ALWAYS, true); GXSetAlphaUpdate(true); GXSetColorUpdate(true); } GXCopyDisp(mToCopyXfb->mBuffer, bUpdate); GXFlush(); GXDrawDone(); u32 interrupts = OSDisableInterrupts(); mToCopyXfb->mState = Xfb::XFB_COPIED; if (mToShowXfb == nullptr) { mToShowXfb = mToCopyXfb; } Xfb *next = mToCopyXfb->mNext->mState == Xfb::XFB_UNPROCESSED ? mToCopyXfb->mNext : nullptr; mToCopyXfb = next; OSRestoreInterrupts(interrupts); } } void XfbManager::setNextFrameBuffer() { if (mToShowXfb != nullptr) { if (mNumXfbs_Copy > 2) { mNumXfbs_Copy -= 1; } else { VISetNextFrameBuffer(mToShowXfb->mBuffer); VIFlush(); nw4r::db::DirectPrint_ChangeXfb(mToShowXfb->mBuffer, mToShowXfb->mWidth, mToShowXfb->mHeight); if (mNumXfbs > 1) { mNextXfb->mState = Xfb::XFB_UNPROCESSED; if (mToCopyXfb == nullptr) { mToCopyXfb = mNextXfb; } mToShowXfb->mState = Xfb::XFB_SHOWN; mNextXfb = mToShowXfb; mToShowXfb = mToShowXfb->mNext->mState == Xfb::XFB_COPIED ? mToShowXfb->mNext : nullptr; } else { mToShowXfb->mState = Xfb::XFB_UNPROCESSED; if (mToCopyXfb == nullptr) { mToCopyXfb = mToShowXfb; } mToShowXfb = nullptr; } } } else { if (mNumXfbs == 1 && mNextXfb != nullptr) { mNextXfb->mState = Xfb::XFB_UNPROCESSED; mToCopyXfb = mNextXfb; } } } } // namespace EGG