diff --git a/include/JSystem/JUtility/JUTVideo.h b/include/JSystem/JUtility/JUTVideo.h index 5f4e35251d8..5660decd258 100644 --- a/include/JSystem/JUtility/JUTVideo.h +++ b/include/JSystem/JUtility/JUTVideo.h @@ -8,7 +8,7 @@ class JUTVideo { public: - typedef void (*CallbackFn)(void); + typedef void (*Callback)(u32); JUTVideo(GXRenderModeObj const*); virtual ~JUTVideo(); @@ -30,8 +30,8 @@ public: private: static JUTVideo* sManager; - static u32 sVideoLastTick; - static u32 sVideoInterval; + static OSTick sVideoLastTick; + static OSTick sVideoInterval; private: /* 0x04 */ _GXRenderModeObj* mRenderObj; @@ -42,12 +42,16 @@ private: /* 0x18 */ u32 field_0x18; /* 0x1C */ VIRetraceCallback mPreRetraceCallback; /* 0x20 */ VIRetraceCallback mPostRetraceCallback; - /* 0x24 */ CallbackFn unknown_callback_1; - /* 0x28 */ CallbackFn unknown_callback_2; + /* 0x24 */ Callback mPreCallback; + /* 0x28 */ Callback mPostCallback; /* 0x2C */ bool mSetBlack; /* 0x30 */ s32 mSetBlackFrameCount; /* 0x34 */ OSMessage mMessage; /* 0x38 */ OSMessageQueue mMessageQueue; }; +inline JUTVideo* JUTGetVideoManager() { + return JUTVideo::getManager(); +} + #endif /* JUTVIDEO_H */ diff --git a/include/JSystem/JUtility/JUTXfb.h b/include/JSystem/JUtility/JUTXfb.h index a523452d252..7a647faa05d 100644 --- a/include/JSystem/JUtility/JUTXfb.h +++ b/include/JSystem/JUtility/JUTXfb.h @@ -23,6 +23,29 @@ public: /* 802E5424 */ static void destroyManager(); /* 802E5454 */ void initiate(u16, u16, JKRHeap*, JUTXfb::EXfbNumber); + s32 getBufferNum() const { return mBufferNum; } + s16 getDrawnXfbIndex() const { return mDrawnXfbIndex; } + s16 getDrawningXfbIndex() const { return mDrawingXfbIndex; } + s16 getDisplayingXfbIndex() const { return mDisplayingXfbIndex; } + s32 getSDrawingFlag() const { return mSDrawingFlag; } + + void* getDisplayingXfb() const { + if (mDisplayingXfbIndex >= 0) + return mBuffer[mDisplayingXfbIndex]; + return NULL; + } + + void setDisplayingXfbIndex(s16 index) { + mDisplayingXfbIndex = index; + } + + void setSDrawingFlag(s32 flag) { + mSDrawingFlag = flag; + } + + static JUTXfb* getManager() { return sManager; } + +private: static JUTXfb* sManager; private: diff --git a/include/dolphin/vi/vi.h b/include/dolphin/vi/vi.h index 586819f535d..c7d223978ba 100644 --- a/include/dolphin/vi/vi.h +++ b/include/dolphin/vi/vi.h @@ -2,9 +2,20 @@ #define VI_H #include "dolphin/types.h" +#include "dolphin/gx/GX.h" typedef void (*VIRetraceCallback)(u32); extern "C" void VIWaitForRetrace(void); +extern "C" void VISetNextFrameBuffer(void*); +extern "C" VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback); +extern "C" VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback); +extern "C" void VIInit(); +extern "C" void VIConfigure(GXRenderModeObj*); +extern "C" void VIFlush(); +extern "C" void* VIGetNextFrameBuffer(); +extern "C" void* VIGetCurrentFrameBuffer(); +extern "C" void VISetBlack(BOOL); +extern "C" u32 VIGetRetraceCount(); #endif /* VI_H */ diff --git a/libs/JSystem/JUtility/JUTVideo.cpp b/libs/JSystem/JUtility/JUTVideo.cpp index 99acf204167..922b5a2810f 100644 --- a/libs/JSystem/JUtility/JUTVideo.cpp +++ b/libs/JSystem/JUtility/JUTVideo.cpp @@ -4,21 +4,19 @@ // #include "JSystem/JUtility/JUTVideo.h" +#include "JSystem/JUtility/JUTXfb.h" #include "dol2asm.h" #include "dolphin/types.h" +#include "dolphin/vi/vi.h" // // Types: // -struct JUTXfb { - static u8 sManager[4 + 4 /* padding */]; -}; - struct JUTDirectPrint { /* 802E456C */ void changeFrameBuffer(void*, u16, u16); - static u8 sDirectPrint[4 + 4 /* padding */]; + static JUTDirectPrint* sDirectPrint; }; // @@ -47,18 +45,8 @@ extern "C" u8 sVideoInterval__8JUTVideo[4]; extern "C" void* __nw__FUl(); extern "C" void __dl__FPv(); extern "C" void changeFrameBuffer__14JUTDirectPrintFPvUsUs(); -extern "C" VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback); -extern "C" VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback); -extern "C" void VIInit(); -extern "C" void VIWaitForRetrace(); -extern "C" void VIConfigure(_GXRenderModeObj*); -extern "C" void VIFlush(); -extern "C" void VISetNextFrameBuffer(); -extern "C" void VIGetNextFrameBuffer(); -extern "C" void VISetBlack(s32); -extern "C" u32 VIGetRetraceCount(); extern "C" void GXSetDrawDone(); -extern "C" void GXCopyDisp(); +extern "C" void GXCopyDisp(void*, BOOL); extern "C" u8 sDirectPrint__14JUTDirectPrint[4 + 4 /* padding */]; extern "C" u8 sManager__6JUTXfb[4 + 4 /* padding */]; @@ -98,10 +86,10 @@ SECTION_DATA extern void* __vt__8JUTVideo[3 + 1 /* padding */] = { }; /* 8045153C-80451540 000A3C 0004+00 2/2 1/1 0/0 .sbss sVideoLastTick__8JUTVideo */ -u32 JUTVideo::sVideoLastTick; +OSTick JUTVideo::sVideoLastTick; /* 80451540-80451544 000A40 0004+00 2/2 1/1 0/0 .sbss sVideoInterval__8JUTVideo */ -u32 JUTVideo::sVideoInterval; +OSTick JUTVideo::sVideoInterval; /* 802E4CF4-802E4DE8 2DF634 00F4+00 1/1 0/0 0/0 .text __ct__8JUTVideoFPC16_GXRenderModeObj */ JUTVideo::JUTVideo(GXRenderModeObj const* param_0) { @@ -120,13 +108,12 @@ JUTVideo::JUTVideo(GXRenderModeObj const* param_0) { sVideoInterval = 670000; mPreRetraceCallback = VISetPreRetraceCallback(preRetraceProc); mPostRetraceCallback = VISetPostRetraceCallback(postRetraceProc); - unknown_callback_1 = NULL; - unknown_callback_2 = NULL; + mPreCallback = NULL; + mPostCallback = NULL; OSInitMessageQueue(&mMessageQueue, &mMessage, 1); GXSetDrawDoneCallback(drawDoneCallback); } - /* 802E4DE8-802E4E50 2DF728 0068+00 1/0 0/0 0/0 .text __dt__8JUTVideoFv */ JUTVideo::~JUTVideo() { VISetPreRetraceCallback(mPreRetraceCallback); @@ -135,33 +122,109 @@ JUTVideo::~JUTVideo() { /* ############################################################################################## */ /* 80451544-80451548 000A44 0004+00 4/4 0/0 0/0 .sbss None */ -static u8 data_80451544[4]; +static bool data_80451544; /* 80451548-8045154C 000A48 0004+00 1/1 0/0 0/0 .sbss frameBuffer$2222 */ static void* frameBuffer; /* 8045154C-80451550 000A4C 0004+00 1/1 0/0 0/0 .sbss None */ -static u8 data_8045154C[4]; +static s8 data_8045154C; /* 802E4E50-802E5088 2DF790 0238+00 1/1 0/0 0/0 .text preRetraceProc__8JUTVideoFUl */ -#pragma push -#pragma optimization_level 0 -#pragma optimizewithasm off -asm void JUTVideo::preRetraceProc(u32 param_0) { - nofralloc -#include "asm/JSystem/JUtility/JUTVideo/preRetraceProc__8JUTVideoFUl.s" +void JUTVideo::preRetraceProc(u32 retrace_count) { + if (!sManager) { + return; + } + + if (sManager->mPreCallback) { + (*sManager->mPreCallback)(retrace_count); + } + + OSTick tick = OSGetTick(); + sVideoInterval = tick - sVideoLastTick; + sVideoLastTick = tick; + + JUTXfb* xfb = JUTXfb::getManager(); + if (!xfb) { + VISetBlack(TRUE); + VIFlush(); + return; + } + + if (!data_8045154C) { + frameBuffer = NULL; + data_8045154C = true; + } + + if (frameBuffer) { + JUTVideo* videoManager = JUTGetVideoManager(); + const GXRenderModeObj* renderMode = videoManager->getRenderMode(); + JUTDirectPrint::sDirectPrint->changeFrameBuffer(frameBuffer, renderMode->fb_width, + renderMode->efb_height); + } + + if (sManager->mSetBlack == 1) { + s32 frame_count = sManager->mSetBlackFrameCount; + if (frame_count > 0) { + frame_count--; + } + + sManager->mSetBlackFrameCount = frame_count; + sManager->mSetBlack = frame_count != 0; + VISetBlack(TRUE); + VIFlush(); + return; + } + + if (!xfb) { + VISetBlack(TRUE); + VIFlush(); + return; + } + + if (xfb->getBufferNum() == 3 || xfb->getBufferNum() == 2) { + if (!data_80451544) { + s16 index = xfb->getDrawnXfbIndex(); + xfb->setDisplayingXfbIndex(index); + if (index < 0) { + VISetBlack(1); + VIFlush(); + } else { + VISetNextFrameBuffer(xfb->getDisplayingXfb()); + VIFlush(); + VISetBlack(FALSE); + frameBuffer = xfb->getDisplayingXfb(); + } + } + } else if (xfb->getBufferNum() == 1) { + if (xfb->getSDrawingFlag() == 0) { + s16 index = xfb->getDrawnXfbIndex(); + if (index >= 0) { + xfb->setDisplayingXfbIndex(index); + GXCopyDisp(xfb->getDisplayingXfb(), 1); + GXFlush(); + xfb->setSDrawingFlag(2); + frameBuffer = xfb->getDisplayingXfb(); + if (VIGetNextFrameBuffer()) { + VISetBlack(FALSE); + } + } else { + VISetBlack(TRUE); + } + } + VIFlush(); + } } -#pragma pop /* 802E5088-802E50B0 2DF9C8 0028+00 0/0 1/1 0/0 .text drawDoneStart__8JUTVideoFv */ void JUTVideo::drawDoneStart() { - data_80451544[0] = 1; + data_80451544 = 1; GXSetDrawDone(); } /* 802E50B0-802E50BC 2DF9F0 000C+00 0/0 1/1 0/0 .text dummyNoDrawWait__8JUTVideoFv */ void JUTVideo::dummyNoDrawWait() { - data_80451544[0] = 0; + data_80451544 = 0; } /* 802E50BC-802E5144 2DF9FC 0088+00 1/1 0/0 0/0 .text drawDoneCallback__8JUTVideoFv */ diff --git a/libs/dolphin/vi/vi.cpp b/libs/dolphin/vi/vi.cpp index 94f7d82ac7d..5807dfcf2f8 100644 --- a/libs/dolphin/vi/vi.cpp +++ b/libs/dolphin/vi/vi.cpp @@ -12,20 +12,10 @@ // extern "C" void __VIRetraceHandler(); -extern "C" void VISetPreRetraceCallback(); -extern "C" void VISetPostRetraceCallback(); extern "C" static void getTiming(); extern "C" void __VIInit(); -extern "C" void VIInit(); -extern "C" void VIWaitForRetrace(); extern "C" static void setFbbRegs(); extern "C" static void setVerticalRegs(); -extern "C" void VIConfigure(); -extern "C" void VIFlush(); -extern "C" void VISetNextFrameBuffer(); -extern "C" u32 VIGetNextFrameBuffer(); -extern "C" u32 VIGetCurrentFrameBuffer(); -extern "C" void VISetBlack(); extern "C" u32 VIGetRetraceCount(); extern "C" static void GetCurrentDisplayPosition(); extern "C" static void getCurrentFieldEvenOdd(); @@ -139,7 +129,7 @@ asm void __VIRetraceHandler() { #pragma push #pragma optimization_level 0 #pragma optimizewithasm off -asm void VISetPreRetraceCallback() { +asm VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback) { nofralloc #include "asm/dolphin/vi/vi/VISetPreRetraceCallback.s" } @@ -149,7 +139,7 @@ asm void VISetPreRetraceCallback() { #pragma push #pragma optimization_level 0 #pragma optimizewithasm off -asm void VISetPostRetraceCallback() { +asm VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback) { nofralloc #include "asm/dolphin/vi/vi/VISetPostRetraceCallback.s" } @@ -772,7 +762,7 @@ static u8 message[4 + 4 /* padding */]; #pragma push #pragma optimization_level 0 #pragma optimizewithasm off -asm void VIConfigure() { +asm void VIConfigure(GXRenderModeObj*) { nofralloc #include "asm/dolphin/vi/vi/VIConfigure.s" } @@ -792,27 +782,27 @@ asm void VIFlush() { #pragma push #pragma optimization_level 0 #pragma optimizewithasm off -asm void VISetNextFrameBuffer() { +asm void VISetNextFrameBuffer(void*) { nofralloc #include "asm/dolphin/vi/vi/VISetNextFrameBuffer.s" } #pragma pop /* 8034D830-8034D838 -00001 0008+00 0/0 0/0 0/0 .text VIGetNextFrameBuffer */ -u32 VIGetNextFrameBuffer() { - return *(u32*)(&NextBufAddr); +void* VIGetNextFrameBuffer() { + return *(void**)(&NextBufAddr); } /* 8034D838-8034D840 -00001 0008+00 0/0 0/0 0/0 .text VIGetCurrentFrameBuffer */ -u32 VIGetCurrentFrameBuffer() { - return *(u32*)(&CurrBufAddr); +void* VIGetCurrentFrameBuffer() { + return *(void**)(&CurrBufAddr); } /* 8034D840-8034D8BC 348180 007C+00 0/0 7/7 0/0 .text VISetBlack */ #pragma push #pragma optimization_level 0 #pragma optimizewithasm off -asm void VISetBlack() { +asm void VISetBlack(BOOL) { nofralloc #include "asm/dolphin/vi/vi/VISetBlack.s" } diff --git a/src/m_Do/m_Do_machine.cpp b/src/m_Do/m_Do_machine.cpp index 743fd95fdab..c4e1f38a2ce 100644 --- a/src/m_Do/m_Do_machine.cpp +++ b/src/m_Do/m_Do_machine.cpp @@ -136,9 +136,6 @@ extern "C" void setDirectConsole__17JUTConsoleManagerFP10JUTConsole(); extern "C" void PPCHalt(); extern "C" u32 OSGetProgressiveMode(); extern "C" void OSSetProgressiveMode(); -extern "C" void VIFlush(); -extern "C" void VISetBlack(s32); -extern "C" void VIGetRetraceCount(); extern "C" void VIGetDTVStatus(); extern "C" void _savegpr_28(); extern "C" void _restgpr_28();