mirror of
https://github.com/zeldaret/ss
synced 2026-07-03 12:30:07 -04:00
eggAsyncDisplay almost
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
#include <egg/core/eggAsyncDisplay.h>
|
||||
#include <egg/math/eggMatrix.h>
|
||||
#include <egg/core/eggXfbManager.h>
|
||||
#include <rvl/GX/GXTexture.h>
|
||||
#include <rvl/GX/GXHardware.h>
|
||||
|
||||
// This file still has incorrect sdata2
|
||||
|
||||
static EGG::AsyncDisplay *lbl_80576790[2];
|
||||
|
||||
namespace EGG {
|
||||
|
||||
AsyncDisplay::AsyncDisplay(u8 maxRetrace): Display(maxRetrace) {
|
||||
this->field_0x98 = 0.0;
|
||||
this->field_0x9C = 0.0;
|
||||
this->field_0xA4 = 0;
|
||||
this->field_0xA8 = 0;
|
||||
this->field_0xAC = 0;
|
||||
this->field_0xB8 = 0;
|
||||
lbl_80576790[0] = this;
|
||||
OSInitThreadQueue(&this->mThreadQueue);
|
||||
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuf, 4);
|
||||
}
|
||||
|
||||
f32 AsyncDisplay::calcS() {
|
||||
f32 tmp = this->field_0x9C + this->field_0xA0;
|
||||
this->field_0x9C = tmp;
|
||||
if (!(tmp > 1.0f)) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (this->mScreenStateFlag.onBit(4)) {
|
||||
this->field_0x9C = tmp - 1.0f;
|
||||
this->mScreenStateFlag.resetBit(4);
|
||||
} else {
|
||||
this->field_0x9C = tmp - this->field_0xA0;
|
||||
this->mScreenStateFlag.setBit(4);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline void AsyncDisplay::waitForMsg(bool b) {
|
||||
// This is really ugly but I couldn't find a different way
|
||||
// to make the compiler use the registers
|
||||
XfbManager *xfb;
|
||||
while (!((xfb = BaseSystem::mConfigData->getXfbMgr(), 1 < xfb->mNumXfbs - this->field_0xAC) && (BaseSystem::mConfigData->getXfbMgr()->mToCopyXfb != nullptr || b))) {
|
||||
|
||||
OSReceiveMessage(&this->mMesgQueue, this->mMesgBuf, 1);
|
||||
|
||||
while (OSReceiveMessage(&this->mMesgQueue, this->mMesgBuf, 0)) {}
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncDisplay::beginFrame() {
|
||||
BaseSystem::mConfigData->getXfbMgr();
|
||||
GXDrawDone();
|
||||
|
||||
if (this->mFlag.onBit(1)) {
|
||||
OSSleepThread(&this->mThreadQueue);
|
||||
}
|
||||
bool b = false;
|
||||
if (BaseSystem::mConfigData->getXfbMgr()->mNumXfbs == 1) {
|
||||
s32 tick = OSGetTick();
|
||||
s32 lastTick = this->mLastTick;
|
||||
if (tick - lastTick > Display::sTickPeriod) {
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
} else {
|
||||
b = false;
|
||||
if (this->field_0x98 == 1 && this->mScreenStateFlag.onBit(6)) {
|
||||
b = true;
|
||||
}
|
||||
|
||||
this->waitForMsg(b);
|
||||
}
|
||||
|
||||
if (b) {
|
||||
this->clearEFB();
|
||||
this->mScreenStateFlag.resetBit(6);
|
||||
GXDrawDone();
|
||||
} else {
|
||||
this->copyEFBtoXFB();
|
||||
}
|
||||
|
||||
if (this->field_0x98 == 1) {
|
||||
this->calcS();
|
||||
}
|
||||
this->field_0xAC++;
|
||||
this->mFrameCount++;
|
||||
this->calcFrequency();
|
||||
}
|
||||
|
||||
void AsyncDisplay::endFrame() {
|
||||
if (this->mScreenStateFlag.onBit(4)) {
|
||||
this->mScreenStateFlag.setBit(5);
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncDisplay::endRender() {
|
||||
if (this->mScreenStateFlag.onBit(5)) {
|
||||
this->mScreenStateFlag.setBit(6);
|
||||
this->mScreenStateFlag.resetBit(5);
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncDisplay::preVRetrace() {
|
||||
s32 tick = OSGetTick();
|
||||
this->mLastTick = tick;
|
||||
if (this->field_0x98 == 0) {
|
||||
u32 a8 = ++this->field_0xA8;
|
||||
if (a8 - this->field_0xA4 >= this->mMaxRetraces) {
|
||||
this->field_0xA4 = a8;
|
||||
this->mScreenStateFlag.setBit(3);
|
||||
OSSendMessage(&this->mMesgQueue, this->mMesgBuf, 0);
|
||||
if (this->field_0xAC > 0) {
|
||||
this->field_0xAC--;
|
||||
}
|
||||
}
|
||||
OSWakeupThread(&this->mThreadQueue);
|
||||
}
|
||||
|
||||
if (this->mScreenStateFlag.onBit(3)) {
|
||||
s32 count = VIGetRetraceCount();
|
||||
if (count - this->mRetraceCount >= this->mMaxRetraces) {
|
||||
if (this->mScreenStateFlag.onBit(0)) {
|
||||
Video *video = BaseSystem::mConfigData->getVideo();
|
||||
VISetBlack(video->mFlag.offBit(0));
|
||||
if (video->mFlag.offBit(0)) {
|
||||
video->mFlag.setBit(0);
|
||||
} else {
|
||||
video->mFlag.resetBit(0);
|
||||
}
|
||||
this->mScreenStateFlag.resetBit(0);
|
||||
}
|
||||
XfbManager *xfb = BaseSystem::mConfigData->getXfbMgr();
|
||||
xfb->setNextFrameBuffer();
|
||||
s32 newCount = VIGetRetraceCount();
|
||||
this->mRetraceCount = newCount;
|
||||
this->mScreenStateFlag.resetBit(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncDisplay::clearEFB() {
|
||||
Video *video = BaseSystem::mConfigData->getVideo();
|
||||
GXRenderModeObj const *renderMode = video->pRenderMode;
|
||||
this->clearEFB(renderMode->fbWidth, renderMode->efbHeight, 0, 0, renderMode->fbWidth, renderMode->efbHeight, this->mClearColor);
|
||||
}
|
||||
|
||||
u32 AsyncDisplay::getTickPerFrame() {
|
||||
if (this->field_0x98 == 1) {
|
||||
return Video::getTickPerVRetrace(0);
|
||||
} else {
|
||||
return Video::getTickPerVRetrace();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO move
|
||||
extern "C" {
|
||||
extern GXTexObj lbl_80673B20, lbl_8056EB20;
|
||||
extern Matrix34f lbl_80674C00;
|
||||
}
|
||||
|
||||
void AsyncDisplay::clearEFB(u16 fbWidth, u16 fbHeight, u16 x, u16 y, u16 width, u16 height, nw4r::ut::Color color) {
|
||||
|
||||
GXInitTexObj(&lbl_80673B20, &lbl_8056EB20, 4, 4, GX_TF_Z24X8, GX_REPEAT, GX_REPEAT, 0);
|
||||
GXInitTexObjLOD(&lbl_80673B20, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
|
||||
Mtx44 mat;
|
||||
C_MTXOrtho(mat, 0.0, (float)fbHeight, 0.0, (float)fbWidth, 0.0, 1.0f);
|
||||
GXSetProjection(mat, GX_ORTHOGRAPHIC);
|
||||
GXSetViewport(0.0, 0.0, (float)fbWidth, (float)fbHeight, 0.0, 1.0f);
|
||||
GXSetScissor(0, 0, fbWidth, fbHeight);
|
||||
lbl_80674C00.loadPosMtx(0);
|
||||
GXSetCurrentMtx(0);
|
||||
GXClearVtxDesc();
|
||||
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGBX8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGB565, 0);
|
||||
GXSetNumChans(0);
|
||||
GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
|
||||
GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
|
||||
GXSetNumTexGens(1);
|
||||
GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, false, 0x7d);
|
||||
GXLoadTexObj(&lbl_80673B20, GX_TEXMAP0);
|
||||
GXSetNumTevStages(1);
|
||||
GXSetTevColor(GX_TEVREG0, color);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_TEV_SCALE_0, 1, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_TEV_SCALE_0, 1, GX_TEVPREV);
|
||||
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0);
|
||||
GXSetZTexture(2, GX_TF_Z24X8, 0);
|
||||
GXSetZCompLoc(false);
|
||||
GXSetBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ZERO, GX_LO_NOOP);
|
||||
GXSetAlphaUpdate(true);
|
||||
GXSetDstAlpha(true, color.a);
|
||||
GXSetZMode(true, GX_ALWAYS, true);
|
||||
GXSetCullMode(GX_CULL_BACK);
|
||||
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
|
||||
|
||||
// The regs are wrong here
|
||||
WGPIPE.us = x;
|
||||
WGPIPE.us = y;
|
||||
WGPIPE.c = 0;
|
||||
WGPIPE.c = 0;
|
||||
WGPIPE.us = x + width;
|
||||
WGPIPE.us = y;
|
||||
WGPIPE.c = 1;
|
||||
WGPIPE.c = 0;
|
||||
WGPIPE.us = x + width;
|
||||
WGPIPE.us = y + height;
|
||||
WGPIPE.c = 1;
|
||||
WGPIPE.c = 1;
|
||||
WGPIPE.us = width;
|
||||
WGPIPE.us = y + height;
|
||||
WGPIPE.c = 0;
|
||||
WGPIPE.c = 1;
|
||||
|
||||
GXSetZTexture(0, GX_TF_Z24X8, 0);
|
||||
GXSetZCompLoc(true);
|
||||
GXSetDstAlpha(false, color.a);
|
||||
}
|
||||
|
||||
} // namespace EGG
|
||||
Reference in New Issue
Block a user