mirror of
https://github.com/encounter/mkdd.git
synced 2026-03-30 11:30:02 -07:00
228 lines
5.4 KiB
C++
228 lines
5.4 KiB
C++
#include <dolphin/vi.h>
|
|
#include "JSystem/JUtility/JUTDirectPrint.h"
|
|
#include "JSystem/JUtility/JUTVideo.h"
|
|
#include "JSystem/JUtility/JUTXfb.h"
|
|
|
|
JUTVideo *JUTVideo::sManager;
|
|
OSTick JUTVideo::sVideoLastTick;
|
|
OSTick JUTVideo::sVideoInterval;
|
|
|
|
bool sDrawWaiting;
|
|
|
|
JUTVideo *JUTVideo::createManager(const _GXRenderModeObj *renderModeObj)
|
|
{
|
|
if (sManager == nullptr)
|
|
{
|
|
sManager = new JUTVideo(renderModeObj);
|
|
}
|
|
return sManager;
|
|
}
|
|
|
|
void JUTVideo::destroyManager()
|
|
{
|
|
if (sManager != nullptr)
|
|
{
|
|
delete sManager;
|
|
sManager = nullptr;
|
|
}
|
|
}
|
|
|
|
JUTVideo::JUTVideo(const _GXRenderModeObj *renderModeObj)
|
|
{
|
|
mRenderModeObj = nullptr;
|
|
VIInit();
|
|
mIsSetBlack = true;
|
|
mSetBlackFrameCount = 2;
|
|
setRenderMode(renderModeObj);
|
|
VISetBlack(TRUE);
|
|
VIFlush();
|
|
_08 = 0;
|
|
mRetraceCount = VIGetRetraceCount();
|
|
_10 = 1;
|
|
_18 = 0;
|
|
sVideoLastTick = OSGetTick();
|
|
sVideoInterval = 670000;
|
|
mPreviousPreRetraceCallback = VISetPreRetraceCallback(preRetraceProc);
|
|
mPreviousPostRetraceCallback = VISetPostRetraceCallback(postRetraceProc);
|
|
mPreRetraceCallback = nullptr;
|
|
mPostRetraceCallback = nullptr;
|
|
OSInitMessageQueue(&mMessageQueue, &mMessage, 1);
|
|
GXSetDrawDoneCallback(drawDoneCallback);
|
|
}
|
|
|
|
JUTVideo::~JUTVideo()
|
|
{
|
|
VISetPreRetraceCallback(mPreviousPreRetraceCallback);
|
|
VISetPostRetraceCallback(mPreviousPostRetraceCallback);
|
|
}
|
|
|
|
void JUTVideo::preRetraceProc(u32 retrace_count)
|
|
{
|
|
if (sManager->mPreRetraceCallback)
|
|
{
|
|
(*sManager->mPreRetraceCallback)(retrace_count);
|
|
}
|
|
|
|
OSTick tick = OSGetTick();
|
|
sVideoInterval = OSDiffTick(tick, sVideoLastTick);
|
|
sVideoLastTick = tick;
|
|
|
|
JUTXfb *xfb = JUTXfb::getManager();
|
|
if (!xfb)
|
|
{
|
|
VISetBlack(TRUE);
|
|
VIFlush();
|
|
return;
|
|
}
|
|
|
|
static void *frameBuffer = nullptr;
|
|
|
|
if (frameBuffer)
|
|
{
|
|
JUTVideo *videoManager = JUTGetVideoManager();
|
|
const GXRenderModeObj *renderMode = videoManager->getRenderMode();
|
|
JUTDirectPrint *directPrint = JUTDirectPrint::getManager();
|
|
directPrint->changeFrameBuffer(frameBuffer, renderMode->fbWidth, renderMode->efbHeight);
|
|
}
|
|
|
|
if (sManager->mIsSetBlack == 1)
|
|
{
|
|
s32 frame_count = sManager->mSetBlackFrameCount;
|
|
if (frame_count > 0)
|
|
{
|
|
frame_count--;
|
|
}
|
|
|
|
sManager->mSetBlackFrameCount = frame_count;
|
|
sManager->mIsSetBlack = frame_count != 0 ? true : false;
|
|
VISetBlack(TRUE);
|
|
VIFlush();
|
|
return;
|
|
}
|
|
|
|
if (!xfb)
|
|
{
|
|
VISetBlack(TRUE);
|
|
VIFlush();
|
|
return;
|
|
}
|
|
|
|
if (xfb->getBufferNum() == 3 || xfb->getBufferNum() == 2)
|
|
{
|
|
if (!sDrawWaiting)
|
|
{
|
|
int index = xfb->getDrawnXfbIndex();
|
|
xfb->setDisplayingXfbIndex(index);
|
|
if ((s16)index < 0)
|
|
{
|
|
VISetBlack(1);
|
|
VIFlush();
|
|
}
|
|
else
|
|
{
|
|
VISetNextFrameBuffer(xfb->getDisplayingXfb());
|
|
VIFlush();
|
|
VISetBlack(FALSE);
|
|
frameBuffer = xfb->getDisplayingXfb();
|
|
}
|
|
}
|
|
}
|
|
else if (xfb->getBufferNum() == 1)
|
|
{
|
|
if (xfb->getSDrawingFlag() == 0)
|
|
{
|
|
int index = xfb->getDrawnXfbIndex();
|
|
if ((s16)index >= 0)
|
|
{
|
|
xfb->setDisplayingXfbIndex(index);
|
|
GXCopyDisp(xfb->getDisplayingXfb(), GX_TRUE);
|
|
GXFlush();
|
|
xfb->setSDrawingFlag(2);
|
|
frameBuffer = xfb->getDisplayingXfb();
|
|
if (VIGetNextFrameBuffer())
|
|
{
|
|
VISetBlack(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
VISetBlack(TRUE);
|
|
}
|
|
}
|
|
VIFlush();
|
|
}
|
|
}
|
|
|
|
void JUTVideo::drawDoneStart()
|
|
{
|
|
sDrawWaiting = true;
|
|
GXSetDrawDone();
|
|
}
|
|
|
|
void JUTVideo::dummyNoDrawWait() { sDrawWaiting = false; }
|
|
|
|
void JUTVideo::drawDoneCallback()
|
|
{
|
|
JUTXfb *xfb = JUTXfb::getManager();
|
|
if (!xfb)
|
|
{
|
|
return;
|
|
}
|
|
|
|
sDrawWaiting = false;
|
|
|
|
if (xfb->getBufferNum() == JUTXfb::SingleBuffer && xfb->getSDrawingFlag() == 1)
|
|
{
|
|
xfb->setSDrawingFlag(0);
|
|
if (xfb->getDrawnXfb())
|
|
{
|
|
VISetNextFrameBuffer(xfb->getDrawnXfb());
|
|
VIFlush();
|
|
}
|
|
}
|
|
}
|
|
|
|
void JUTVideo::postRetraceProc(u32 p1)
|
|
{
|
|
if (sManager->mPostRetraceCallback != nullptr)
|
|
{
|
|
sManager->mPostRetraceCallback(p1);
|
|
}
|
|
u32 retraceCount = VIGetRetraceCount();
|
|
OSSendMessage(&sManager->mMessageQueue, (void *)retraceCount, OS_MESSAGE_NOBLOCK);
|
|
}
|
|
|
|
void JUTVideo::setRenderMode(const GXRenderModeObj *newRenderModeObj)
|
|
{
|
|
if (mRenderModeObj && newRenderModeObj->viTVmode != mRenderModeObj->viTVmode)
|
|
{
|
|
mIsSetBlack = true;
|
|
mSetBlackFrameCount = 4;
|
|
}
|
|
|
|
mRenderModeObj = (GXRenderModeObj *)newRenderModeObj;
|
|
VIConfigure(mRenderModeObj);
|
|
VIFlush();
|
|
|
|
if (mIsSetBlack)
|
|
{
|
|
VIWaitForRetrace();
|
|
VIWaitForRetrace();
|
|
}
|
|
}
|
|
|
|
void JUTVideo::waitRetraceIfNeed() {}
|
|
|
|
VIRetraceCallback JUTVideo::setPreRetraceCallback(VIRetraceCallback newCB)
|
|
{
|
|
VIRetraceCallback oldCB = mPreRetraceCallback;
|
|
mPreRetraceCallback = newCB;
|
|
return oldCB;
|
|
}
|
|
|
|
VIRetraceCallback JUTVideo::setPostRetraceCallback(VIRetraceCallback newCB)
|
|
{
|
|
VIRetraceCallback oldCB = mPostRetraceCallback;
|
|
mPostRetraceCallback = newCB;
|
|
return oldCB;
|
|
} |