Files
SwareJonge aae7a5f030 fix not OK
2023-08-24 18:59:43 +02:00

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;
}