From b35d67e5550230075d7b8aa6d121d460a4c6409e Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 27 Apr 2024 09:55:06 +0200 Subject: [PATCH 1/6] eggAsyncDisplay almost --- config/SOUE01/symbols.txt | 20 +-- include/egg/core/eggAsyncDisplay.h | 16 +- include/rvl/GX/GXTev.h | 2 +- src/egg/core/eggAsyncDisplay.cpp | 226 +++++++++++++++++++++++++++++ 4 files changed, 242 insertions(+), 22 deletions(-) create mode 100644 src/egg/core/eggAsyncDisplay.cpp diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 7b943c29..5c047dc9 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -21976,9 +21976,9 @@ fn_803A9B10 = .text:0x803A9B10; // type:function size:0x240 fn_803A9D50 = .text:0x803A9D50; // type:function size:0x1D4 __OSModuleInit = .text:0x803A9F30; // type:function size:0x18 scope:global fn_803A9F50 = .text:0x803A9F50; // type:function size:0xA4 -fn_803AA000 = .text:0x803AA000; // type:function size:0x60 -fn_803AA060 = .text:0x803AA060; // type:function size:0xC8 -fn_803AA130 = .text:0x803AA130; // type:function size:0xDC +OSInitMessageQueue = .text:0x803AA000; // type:function size:0x60 +OSSendMessage = .text:0x803AA060; // type:function size:0xC8 +OSReceiveMessage = .text:0x803AA130; // type:function size:0xDC fn_803AA210 = .text:0x803AA210; // type:function size:0xC OSGetPhysicalMem2Size = .text:0x803AA220; // type:function size:0xC scope:global OSGetConsoleSimulatedMem1Size = .text:0x803AA230; // type:function size:0xC scope:global @@ -22052,7 +22052,7 @@ fn_803AD330 = .text:0x803AD330; // type:function size:0xA0 fn_803AD3D0 = .text:0x803AD3D0; // type:function size:0x29C fn_803AD670 = .text:0x803AD670; // type:function size:0x18C OSSleepThread = .text:0x803AD800; // type:function size:0xF0 scope:global -fn_803AD8F0 = .text:0x803AD8F0; // type:function size:0xF8 +OSWakeupThread = .text:0x803AD8F0; // type:function size:0xF8 fn_803AD9F0 = .text:0x803AD9F0; // type:function size:0xEC fn_803ADAE0 = .text:0x803ADAE0; // type:function size:0x8 OSGetTime = .text:0x803ADAF0; // type:function size:0x18 scope:global @@ -22324,7 +22324,7 @@ GXLoadLightObjImm = .text:0x803BE790; // type:function size:0x80 GXSetChanAmbColor = .text:0x803BE810; // type:function size:0xD8 GXSetChanMatColor = .text:0x803BE8F0; // type:function size:0xD8 GXSetNumChans = .text:0x803BE9D0; // type:function size:0x24 -GXSetChanCtr1 = .text:0x803BEA00; // type:function size:0xA4 +GXSetChanCtrl = .text:0x803BEA00; // type:function size:0xA4 GXGetTexBufferSize = .text:0x803BEAB0; // type:function size:0x124 __GetImageTileCount = .text:0x803BEBE0; // type:function size:0xC0 GXInitTexObj = .text:0x803BECA0; // type:function size:0x20C @@ -22386,7 +22386,7 @@ GXSetTevKAlphaSel = .text:0x803C0700; // type:function size:0x50 GXSetTevSwapMode = .text:0x803C0750; // type:function size:0x3C GXSetTevSwapModeTable = .text:0x803C0790; // type:function size:0x7C GXSetAlphaCompare = .text:0x803C0810; // type:function size:0x38 -GXSsetZTexture = .text:0x803C0850; // type:function size:0x84 +GXSetZTexture = .text:0x803C0850; // type:function size:0x84 GXSetTevOrder = .text:0x803C08E0; // type:function size:0x15C GXSetNumTevStages = .text:0x803C0A40; // type:function size:0x24 GXSetFog = .text:0x803C0A70; // type:function size:0x22C @@ -26275,7 +26275,7 @@ getTickPerFrame__Q23EGG7DisplayFv = .text:0x804975F0; // type:function size:0x4 beginFrame__Q23EGG7DisplayFv = .text:0x80497600; // type:function size:0xB8 beginRender__Q23EGG7DisplayFv = .text:0x804976C0; // type:function size:0x4 endRender__Q23EGG7DisplayFv = .text:0x804976D0; // type:function size:0x4 -endgFrame__Q23EGG7DisplayFv = .text:0x804976E0; // type:function size:0x4 +endFrame__Q23EGG7DisplayFv = .text:0x804976E0; // type:function size:0x4 preVRetrace__Q23EGG7DisplayFv = .text:0x804976F0; // type:function size:0xDC copyEFBtoXFB__Q23EGG7DisplayFv = .text:0x804977D0; // type:function size:0x9C calcFrequency__Q23EGG7DisplayFv = .text:0x80497870; // type:function size:0x84 @@ -26290,7 +26290,7 @@ calc__Q23EGG10ColorFaderFv = .text:0x80497AB0; // type:function size:0xE4 draw__Q23EGG10ColorFaderFv = .text:0x80497BA0; // type:function size:0x29C __ct__Q23EGG12AsyncDisplayFUc = .text:0x80497E40; // type:function size:0x78 calcS__Q23EGG12AsyncDisplayFv = .text:0x80497EC0; // type:function size:0x58 -beginFrame__Q23EGG12AsyncDisplayFb = .text:0x80497F20; // type:function size:0x19C +beginFrame__Q23EGG12AsyncDisplayFv = .text:0x80497F20; // type:function size:0x19C endFrame__Q23EGG12AsyncDisplayFv = .text:0x804980C0; // type:function size:0x1C endRender__Q23EGG12AsyncDisplayFv = .text:0x804980E0; // type:function size:0x20 preVRetrace__Q23EGG12AsyncDisplayFv = .text:0x80498100; // type:function size:0x15C @@ -26299,7 +26299,7 @@ getTickPerFrame__Q23EGG12AsyncDisplayFv = .text:0x804982D0; // type:function siz clearEFB__Q23EGG12AsyncDisplayFUsUsUsUsUsUsQ34nw4r2ut5Color = .text:0x804982F0; // type:function size:0x398 initialize__Q23EGG5VideoFP16_GXRenderModeObjPCQ33EGG5Video16RenderModeObjSet = .text:0x80498690; // type:function size:0x54 configure__Q23EGG5VideoFP16_GXRenderModeObjPCQ33EGG5Video16RenderModeObjSet = .text:0x804986F0; // type:function size:0x104 -getTickPerVRetrace__Q23EGG5VideoFUl = .text:0x80498800; // type:function size:0x60 +getTickPerVRetrace__Q23EGG5VideoFUi = .text:0x80498800; // type:function size:0x60 getTickPerVRetrace__Q23EGG5VideoFv = .text:0x80498860; // type:function size:0x24 getStandardRenderModeObj__Q23EGG5VideoFv = .text:0x80498890; // type:function size:0x148 init__Q23EGG3XfbFUsUsPQ23EGG4Heap = .text:0x804989E0; // type:function size:0x74 @@ -37104,7 +37104,7 @@ lbl_8056EA58 = .data:0x8056EA58; // type:object size:0x70 __vt__Q23EGG7Display = .data:0x8056EAC8; // type:object size:0x20 lbl_8056EAE8 = .data:0x8056EAE8; // type:object size:0x38 lbl_8056EB20 = .data:0x8056EB20; // type:object size:0x40 -lbl_8056EB60 = .data:0x8056EB60; // type:object size:0x20 +__vt__Q23EGG12AsyncDisplay = .data:0x8056EB60; // type:object size:0x20 lbl_8056EB80 = .data:0x8056EB80; // type:object size:0x10 lbl_8056EB90 = .data:0x8056EB90; // type:object size:0x18 lbl_8056EBA8 = .data:0x8056EBA8; // type:object size:0xC diff --git a/include/egg/core/eggAsyncDisplay.h b/include/egg/core/eggAsyncDisplay.h index b8d94789..36109cbc 100644 --- a/include/egg/core/eggAsyncDisplay.h +++ b/include/egg/core/eggAsyncDisplay.h @@ -15,12 +15,14 @@ public: /* vt 0x18 | 804982d0 */ virtual u32 getTickPerFrame(); /* vt 0x1C | 80498100 */ virtual void preVRetrace(); +private: + inline void waitForMsg(bool); + public: /* 0x2C */ char field_0x2C[0x60 - 0x2C]; /* 0x60 */ OSThreadQueue mThreadQueue; /* 0x68 */ OSMessageQueue mMesgQueue; - /* 0x88 */ OSMessage mMesg; - /* 0x8C */ char field_0x8C[0x98 - 0x8C]; + /* 0x88 */ OSMessage mMesgBuf[4]; /* 0x98 */ s32 field_0x98; /* 0x9C */ f32 field_0x9C; /* 0xA0 */ f32 field_0xA0; @@ -34,19 +36,11 @@ public: public: /* 80497e40 */ AsyncDisplay(u8 maxRetrace); - /* 80497ec0 */ void calcS(); + /* 80497ec0 */ f32 calcS(); /* 80498260 */ void clearEFB(); /* 804982f0 */ void clearEFB(u16, u16, u16, u16, u16, u16, nw4r::ut::Color); }; } // namespace EGG -#ifdef __cplusplus -extern "C" { -#endif -/* 80576790 */ static EGG::AsyncDisplay *spSelector; -#ifdef __cplusplus -} -#endif - #endif diff --git a/include/rvl/GX/GXTev.h b/include/rvl/GX/GXTev.h index c53c04b6..5e4438b0 100644 --- a/include/rvl/GX/GXTev.h +++ b/include/rvl/GX/GXTev.h @@ -21,7 +21,7 @@ void GXSetTevSwapMode(GXTevStageID, GXTevSwapSel, GXTevSwapSel); void GXSetTevSwapModeTable(GXTevSwapSel, GXTevColorChan, GXTevColorChan, GXTevColorChan, GXTevColorChan); void GXSetAlphaCompare(GXCompare, u8, GXAlphaOp, GXCompare, u8); -void GXSetZTexture(UNKWORD, UNKWORD, UNKWORD); +void GXSetZTexture(UNKWORD, GXTexFmt, u32); void GXSetTevOrder(GXTevStageID, GXTexCoordID, GXTexMapID, GXChannelID); void GXSetNumTevStages(u8); diff --git a/src/egg/core/eggAsyncDisplay.cpp b/src/egg/core/eggAsyncDisplay.cpp new file mode 100644 index 00000000..8aaf943c --- /dev/null +++ b/src/egg/core/eggAsyncDisplay.cpp @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include + +// 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 From 010a351e4d874dd4d479986bd8f87c29523505fc Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 27 Apr 2024 15:07:18 +0200 Subject: [PATCH 2/6] Use GXPosition functions --- src/egg/core/eggAsyncDisplay.cpp | 34 +++++++++++++------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/egg/core/eggAsyncDisplay.cpp b/src/egg/core/eggAsyncDisplay.cpp index 8aaf943c..258c7145 100644 --- a/src/egg/core/eggAsyncDisplay.cpp +++ b/src/egg/core/eggAsyncDisplay.cpp @@ -11,8 +11,8 @@ 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_0x98 = 0; + this->field_0x9C = 0.0f; this->field_0xA4 = 0; this->field_0xA8 = 0; this->field_0xAC = 0; @@ -166,9 +166,9 @@ void AsyncDisplay::clearEFB(u16 fbWidth, u16 fbHeight, u16 x, u16 y, u16 width, 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); + C_MTXOrtho(mat, 0.0, fbHeight, 0.0, fbWidth, 0.0, 1.0f); GXSetProjection(mat, GX_ORTHOGRAPHIC); - GXSetViewport(0.0, 0.0, (float)fbWidth, (float)fbHeight, 0.0, 1.0f); + GXSetViewport(0.0, 0.0, fbWidth, fbHeight, 0.0, 1.0f); GXSetScissor(0, 0, fbWidth, fbHeight); lbl_80674C00.loadPosMtx(0); GXSetCurrentMtx(0); @@ -201,22 +201,16 @@ void AsyncDisplay::clearEFB(u16 fbWidth, u16 fbHeight, u16 x, u16 y, u16 width, 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; + GXPosition2u16(x, y); + GXPosition2u8(0, 0); + GXPosition2u16(x + width, y); + GXPosition2u8(1, 0); + GXPosition2u16(x + width, y + height); + GXPosition2u8(1, 1); + GXPosition2u16(width, y + height); + GXPosition2u8(0, 1); + + // GXEnd(); GXSetZTexture(0, GX_TF_Z24X8, 0); GXSetZCompLoc(true); From 00765b2fb0b05d01b0c3f1606383fbf5b82ecf1a Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 27 Apr 2024 16:19:58 +0200 Subject: [PATCH 3/6] Fix registers --- src/egg/core/eggAsyncDisplay.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/egg/core/eggAsyncDisplay.cpp b/src/egg/core/eggAsyncDisplay.cpp index 258c7145..f4d41219 100644 --- a/src/egg/core/eggAsyncDisplay.cpp +++ b/src/egg/core/eggAsyncDisplay.cpp @@ -200,14 +200,15 @@ void AsyncDisplay::clearEFB(u16 fbWidth, u16 fbHeight, u16 x, u16 y, u16 width, GXSetCullMode(GX_CULL_BACK); GXBegin(GX_QUADS, GX_VTXFMT0, 4); - // The regs are wrong here GXPosition2u16(x, y); GXPosition2u8(0, 0); - GXPosition2u16(x + width, y); + u16 tmp = x + width; + GXPosition2u16(tmp, y); GXPosition2u8(1, 0); - GXPosition2u16(x + width, y + height); + u16 tmp2 = y + height; + GXPosition2u16(tmp, tmp2); GXPosition2u8(1, 1); - GXPosition2u16(width, y + height); + GXPosition2u16(x, tmp2); GXPosition2u8(0, 1); // GXEnd(); From e0aa69ec362fdd2236b0dcae87c4b00c2a8a5594 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 27 Apr 2024 16:30:14 +0200 Subject: [PATCH 4/6] eggAsyncDisplay matching --- config/SOUE01/splits.txt | 2 +- configure.py | 2 +- src/egg/core/eggAsyncDisplay.cpp | 17 ++++++++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 903c993c..817dcc7e 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -244,7 +244,7 @@ egg/core/eggAsyncDisplay.cpp: .text start:0x80497E40 end:0x80498688 .data start:0x8056EB60 end:0x8056EB80 .sbss start:0x80576790 end:0x80576798 - .sdata2 start:0x8057F310 end:0x8057F328 + .sdata2 start:0x8057F310 end:0x8057F324 egg/core/eggVideo.cpp: .text start:0x80498690 end:0x804989D8 diff --git a/configure.py b/configure.py index fc454981..7eec2a17 100644 --- a/configure.py +++ b/configure.py @@ -336,7 +336,7 @@ config.libs = [ Object(NonMatching, "egg/core/eggSystem.cpp"), Object(Matching, "egg/core/eggDisplay.cpp"), Object(NonMatching, "egg/core/eggColorFader.cpp"), - Object(NonMatching, "egg/core/eggAsyncDisplay.cpp"), + Object(Matching, "egg/core/eggAsyncDisplay.cpp"), Object(NonMatching, "egg/core/eggVideo.cpp"), Object(NonMatching, "egg/core/eggXfb.cpp"), Object(NonMatching, "egg/core/eggXfbManager.cpp"), diff --git a/src/egg/core/eggAsyncDisplay.cpp b/src/egg/core/eggAsyncDisplay.cpp index f4d41219..8b2365bd 100644 --- a/src/egg/core/eggAsyncDisplay.cpp +++ b/src/egg/core/eggAsyncDisplay.cpp @@ -4,15 +4,26 @@ #include #include -// This file still has incorrect sdata2 - static EGG::AsyncDisplay *lbl_80576790[2]; +// Hacks for float ordering +static f32 one() { + return 1.0f; +} + +static f64 cast() { + return 4503599627370496.0; +} + +static f32 zero() { + return 0.0f; +} + namespace EGG { AsyncDisplay::AsyncDisplay(u8 maxRetrace): Display(maxRetrace) { this->field_0x98 = 0; - this->field_0x9C = 0.0f; + this->field_0x9C = 1.0f; this->field_0xA4 = 0; this->field_0xA8 = 0; this->field_0xAC = 0; From 8263b21dacc67b6be72324b76fae795b58df5567 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 27 Apr 2024 16:36:50 +0200 Subject: [PATCH 5/6] final cleanup --- src/egg/core/eggAsyncDisplay.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/egg/core/eggAsyncDisplay.cpp b/src/egg/core/eggAsyncDisplay.cpp index 8b2365bd..0865b526 100644 --- a/src/egg/core/eggAsyncDisplay.cpp +++ b/src/egg/core/eggAsyncDisplay.cpp @@ -36,16 +36,14 @@ AsyncDisplay::AsyncDisplay(u8 maxRetrace): Display(maxRetrace) { 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); + if (tmp > 1.0f) { + 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; } From 05259b75e348e974697cb497b5e3d8fb78e4b376 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Thu, 2 May 2024 13:14:22 -0400 Subject: [PATCH 6/6] fix externs/symbols/splits --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 8 +++--- include/egg/math/eggMatrix.h | 2 +- src/egg/core/eggAsyncDisplay.cpp | 45 ++++++++++++++++++-------------- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 73f7cbd5..1f79f5f6 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -256,6 +256,7 @@ egg/core/eggAsyncDisplay.cpp: .data start:0x8056EB10 end:0x8056EB80 .sbss start:0x80576790 end:0x80576798 .sdata2 start:0x8057F310 end:0x8057F324 + .bss start:0x80673B20 end:0x80673B40 egg/core/eggVideo.cpp: .text start:0x80498690 end:0x804989D8 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index fcbbdeb5..dfd2e61c 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -37103,7 +37103,7 @@ lbl_8056EA40 = .data:0x8056EA40; // type:object size:0x18 lbl_8056EA58 = .data:0x8056EA58; // type:object size:0x70 __vt__Q23EGG7Display = .data:0x8056EAC8; // type:object size:0x20 __vt__Q23EGG10ColorFader = .data:0x8056EAE8; // type:object size:0x24 -lbl_8056EB20 = .data:0x8056EB20; // type:object size:0x40 +clear_z_TX__29@unnamed@eggAsyncDisplay_cpp@ = .data:0x8056EB20; // type:object size:0x40 scope:local __vt__Q23EGG12AsyncDisplay = .data:0x8056EB60; // type:object size:0x20 lbl_8056EB80 = .data:0x8056EB80; // type:object size:0x10 lbl_8056EB90 = .data:0x8056EB90; // type:object size:0x18 @@ -40890,7 +40890,7 @@ lbl_80576770 = .sbss:0x80576770; // type:object size:0x8 data:4byte lbl_80576778 = .sbss:0x80576778; // type:object size:0x8 data:4byte mConfigData__Q23EGG10BaseSystem = .sbss:0x80576780; // type:object size:0x4 data:4byte sTickPeriod__Q23EGG7Display = .sbss:0x80576788; // type:object size:0x4 data:4byte -lbl_80576790 = .sbss:0x80576790; // type:object size:0x8 data:4byte +spSelector = .sbss:0x80576790; // type:object size:0x4 data:4byte lbl_80576798 = .sbss:0x80576798; // type:object size:0x4 data:4byte lbl_8057679C = .sbss:0x8057679C; // type:object size:0xC lbl_805767A8 = .sbss:0x805767A8; // type:object size:0x4 data:4byte @@ -49344,9 +49344,9 @@ lbl_80673AD8 = .bss:0x80673AD8; // type:object size:0x10 lbl_80673AE8 = .bss:0x80673AE8; // type:object size:0x10 lbl_80673AF8 = .bss:0x80673AF8; // type:object size:0x18 lbl_80673B10 = .bss:0x80673B10; // type:object size:0x10 -lbl_80673B20 = .bss:0x80673B20; // type:object size:0x20 +clear_z_tobj__29@unnamed@eggAsyncDisplay_cpp@ = .bss:0x80673B20; // type:object size:0x20 scope:local lbl_80673B40 = .bss:0x80673B40; // type:object size:0x10C0 data:4byte -lbl_80674C00 = .bss:0x80674C00; // type:object size:0x30 +ident__Q23EGG9Matrix34f = .bss:0x80674C00; // type:object size:0x30 zero__Q23EGG8Vector3f = .bss:0x80674C30; // type:object size:0xC data:float ex__Q23EGG8Vector3f = .bss:0x80674C3C; // type:object size:0xC data:float ey__Q23EGG8Vector3f = .bss:0x80674C48; // type:object size:0xC data:float diff --git a/include/egg/math/eggMatrix.h b/include/egg/math/eggMatrix.h index dd944f56..8ce8580c 100644 --- a/include/egg/math/eggMatrix.h +++ b/include/egg/math/eggMatrix.h @@ -90,7 +90,7 @@ public: ////////////////////////////////////////////////////////////////////////////// public: - /* 80674c00 */ static const Matrix34f ident; + /* 80674c00 */ static Matrix34f ident; }; } // namespace EGG diff --git a/src/egg/core/eggAsyncDisplay.cpp b/src/egg/core/eggAsyncDisplay.cpp index 0865b526..7a128d55 100644 --- a/src/egg/core/eggAsyncDisplay.cpp +++ b/src/egg/core/eggAsyncDisplay.cpp @@ -1,10 +1,23 @@ #include -#include #include -#include +#include #include +#include -static EGG::AsyncDisplay *lbl_80576790[2]; +// TODO: Find the proper place for this symbol? - Ghidra has it literally unused +extern "C" static EGG::Display *spSelector; + +namespace { +static GXTexObj clear_z_tobj; +// clang-format off +u8 clear_z_TX[64] ALIGN(32) = { + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; +// clang-format on +} // namespace // Hacks for float ordering static f32 one() { @@ -21,14 +34,14 @@ static f32 zero() { namespace EGG { -AsyncDisplay::AsyncDisplay(u8 maxRetrace): Display(maxRetrace) { +AsyncDisplay::AsyncDisplay(u8 maxRetrace) : Display(maxRetrace) { this->field_0x98 = 0; this->field_0x9C = 1.0f; this->field_0xA4 = 0; this->field_0xA8 = 0; this->field_0xAC = 0; this->field_0xB8 = 0; - lbl_80576790[0] = this; + spSelector = this; OSInitThreadQueue(&this->mThreadQueue); OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuf, 4); } @@ -52,8 +65,8 @@ 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))) { - + 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)) {} @@ -153,7 +166,8 @@ void AsyncDisplay::preVRetrace() { 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); + this->clearEFB(renderMode->fbWidth, renderMode->efbHeight, 0, 0, renderMode->fbWidth, renderMode->efbHeight, + this->mClearColor); } u32 AsyncDisplay::getTickPerFrame() { @@ -164,22 +178,15 @@ u32 AsyncDisplay::getTickPerFrame() { } } -// 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); + GXInitTexObj(&clear_z_tobj, &clear_z_TX, 4, 4, GX_TF_Z24X8, GX_REPEAT, GX_REPEAT, 0); + GXInitTexObjLOD(&clear_z_tobj, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1); Mtx44 mat; C_MTXOrtho(mat, 0.0, fbHeight, 0.0, fbWidth, 0.0, 1.0f); GXSetProjection(mat, GX_ORTHOGRAPHIC); GXSetViewport(0.0, 0.0, fbWidth, fbHeight, 0.0, 1.0f); GXSetScissor(0, 0, fbWidth, fbHeight); - lbl_80674C00.loadPosMtx(0); + Matrix34f::ident.loadPosMtx(0); GXSetCurrentMtx(0); GXClearVtxDesc(); GXSetVtxDesc(GX_VA_POS, GX_DIRECT); @@ -191,7 +198,7 @@ void AsyncDisplay::clearEFB(u16 fbWidth, u16 fbHeight, u16 x, u16 y, u16 width, 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); + GXLoadTexObj(&clear_z_tobj, GX_TEXMAP0); GXSetNumTevStages(1); GXSetTevColor(GX_TEVREG0, color); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);