diff --git a/configure.py b/configure.py index 08892f97..20859932 100644 --- a/configure.py +++ b/configure.py @@ -369,7 +369,7 @@ config.libs = [ Object(Matching, "egg/core/eggXfb.cpp"), Object(Matching, "egg/core/eggVideo.cpp"), Object(Matching, "egg/core/eggXfb.cpp"), - Object(NonMatching, "egg/core/eggXfbManager.cpp"), + Object(Matching, "egg/core/eggXfbManager.cpp"), Object(Matching, "egg/core/eggGraphicsFifo.cpp"), Object(NonMatching, "egg/core/eggController.cpp"), ], diff --git a/include/egg/core/eggXfbManager.h b/include/egg/core/eggXfbManager.h index a0895d85..948b0349 100644 --- a/include/egg/core/eggXfbManager.h +++ b/include/egg/core/eggXfbManager.h @@ -14,7 +14,7 @@ public: /* 0xC */ u8 mNumXfbs; // Total number of Xfbs ever attached /* 0xD */ u8 mNumXfbs_Copy; // Unsure of purpose yet, but showing wont proceed until its under 3 public: - /* 80498af0 */ bool isRegisterd(Xfb *xfb) const; // yes. this is correct spelling + /* 80498af0 */ bool isRegisterd(Xfb &xfb) const; // yes. this is correct spelling /* 80498b30 */ bool attach(Xfb *xfb); /* 80498c10 */ void copyEFB(bool); /* 80498d00 */ void setNextFrameBuffer(); diff --git a/include/rvl/GX/GXFrameBuf.h b/include/rvl/GX/GXFrameBuf.h index f21de91f..7e8592b5 100644 --- a/include/rvl/GX/GXFrameBuf.h +++ b/include/rvl/GX/GXFrameBuf.h @@ -28,6 +28,7 @@ f32 GXGetYScaleFactor(u16 height, u16 width); u16 GXGetNumXfbLines(u16 height, f32 scale); void GXSetDispCopyDst(u16 width, u16 height); u32 GXSetDispCopyYScale(f32 scale); +void GXCopyDisp(void *data, GXBool bUpdate); extern GXRenderModeObj GXNtsc480IntDf; extern GXRenderModeObj GXMpal480IntDf; diff --git a/src/egg/core/eggXfbManager.cpp b/src/egg/core/eggXfbManager.cpp new file mode 100644 index 00000000..46ab8d2a --- /dev/null +++ b/src/egg/core/eggXfbManager.cpp @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include + +namespace EGG { + +/* 80498af0 */ 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; +} + +/* 80498b30 */ 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; +} +/* 80498c10 */ 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); + } +} + +/* 80498d00 */ 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