diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index dbcdfd2d..28f699b9 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2191,6 +2191,7 @@ egg/gfx/eggCpuTexture.cpp: egg/gfx/eggDrawGX.cpp: .text start:0x8049ECA0 end:0x804A0C24 .ctors start:0x804DB998 end:0x804DB99C + .sdata2 start:0x8057F440 end:0x8057F584 egg/gfx/eggDrawPathBase.cpp: .text start:0x804A0C30 end:0x804A0E98 diff --git a/include/egg/gfx/eggDrawGX.h b/include/egg/gfx/eggDrawGX.h index 6fe69326..e72d2cf8 100644 --- a/include/egg/gfx/eggDrawGX.h +++ b/include/egg/gfx/eggDrawGX.h @@ -14,7 +14,7 @@ class DrawGX { public: // made up struct DLData { - void *mpList; + u8 *mpList; u32 mLen; }; @@ -83,6 +83,7 @@ public: static GXTexMapID GetTexMapDefault(); static void LoadTexture(const EGG::ResTIMG *, GXTexMapID); static void BeginDrawScreen(bool, bool, bool); + static void CreateDisplayList(EGG::Heap*); static void DrawDL(enum DL, const nw4r::math::MTX34 &, GXColor); static void SetVtxState(enum VtxType); static void SetBlendMode(enum Blend); @@ -93,7 +94,7 @@ public: static Matrix34f s_cameraMtx; - /* static ?? s_flag */ + static u32 s_flag; static GXColor BLACK; static GXColor WHITE; diff --git a/include/rvl/OS/OSFastCast.h b/include/rvl/OS/OSFastCast.h index 9f86bac7..8780217f 100644 --- a/include/rvl/OS/OSFastCast.h +++ b/include/rvl/OS/OSFastCast.h @@ -10,7 +10,7 @@ extern "C" { #define OS_GQR_TYPE_S8 6 #define OS_GQR_TYPE_S16 7 -static void OSInitFastCast(void) { +static inline void OSInitFastCast(void) { // clang-format off asm { li r3, 4 diff --git a/src/egg/gfx/eggDrawGX.cpp b/src/egg/gfx/eggDrawGX.cpp index 8f7b8d2a..f27d08af 100644 --- a/src/egg/gfx/eggDrawGX.cpp +++ b/src/egg/gfx/eggDrawGX.cpp @@ -1,3 +1,197 @@ #include "egg/gfx/eggDrawGX.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "math.h" +#include "nw4r/math/math_triangular.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXDisplayList.h" +#include "rvl/GX/GXDraw.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/GX/GXVert.h" +#include "rvl/MTX/mtx.h" +#include "rvl/OS/OSCache.h" + +namespace { + +static void DrawQuadNormal(u8, u8, u8, u8, u8) {} +static void DrawQuadLineStripNormal(u8, u8, u8, u8, u8) {} +static void DrawCircleYPolygonFan(const nw4r::math::MTX34 &mtx, f32, u16) {} + +} // namespace + +namespace EGG { + + +extern "C" u8 lbl_8057F528[]; +// Halp +void DrawGX::CreateDisplayList(EGG::Heap *pHeap) { + u8 tmpDisplayList[16 * 1024]; + + OSInitFastCast(); + + DLData *dl = s_DL; + u8 *dat = lbl_8057F528; + + for (int i = 0; i < DL_MAX; i++) { + DCInvalidateRange(tmpDisplayList, sizeof(tmpDisplayList)); + GXBeginDisplayList(tmpDisplayList, sizeof(tmpDisplayList)); + switch ((DL)i) { + case DL_0: + GXSetChanMatColor(GX_COLOR0A0, RED); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, 0.0f); + GXPosition3f32(1.0f, 0.0f, 0.0f); + GXSetChanMatColor(GX_COLOR0A0, GREEN); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, 0.0f); + GXPosition3f32(0.0f, 1.0f, 0.0f); + GXSetChanMatColor(GX_COLOR0A0, BLUE); + GXBegin(GX_LINES, GX_VTXFMT0, 2); + GXPosition3f32(0.0f, 0.0f, 0.0f); + GXPosition3f32(0.0f, 0.0f, 1.0f); + break; + case DL_1: + GXBegin(GX_QUADS, GX_VTXFMT0, 6 * 4); + DrawQuadNormal(1, 5, 4, 0, 0); + DrawQuadNormal(3, 7, 6, 2, 1); + DrawQuadNormal(5, 6, 7, 4, 2); + DrawQuadNormal(3, 2, 1, 0, 3); + DrawQuadNormal(0, 4, 7, 3, 4); + DrawQuadNormal(2, 6, 5, 1, 5); + break; + case DL_2: + DrawQuadLineStripNormal(1, 5, 4, 0, 0); + DrawQuadLineStripNormal(3, 7, 6, 2, 1); + DrawQuadLineStripNormal(5, 6, 7, 4, 2); + DrawQuadLineStripNormal(3, 2, 1, 0, 3); + break; + case DL_3: GXDrawSphere(4, 8); break; + case DL_4: GXDrawSphere(8, 16); break; + case DL_5: + case DL_6: { + u16 numSegments = dat[i - DL_5] + 1; + f32 radPerSegment = 2.0f * M_PI / (numSegments - 1); + GXBegin(GX_LINESTRIP, GX_VTXFMT0, numSegments); + for (int i = 0; i < numSegments; i++) { + GXPosition3f32( + nw4r::math::CosRad(i * radPerSegment) / 2.0f, nw4r::math::SinRad(i * radPerSegment) / 2.0f, 0.0f + ); + } + break; + } + case DL_9: + case DL_10: { + u16 numSegments = dat[i - DL_9] + 1; + f32 radPerSegment = 2.0f * M_PI / (numSegments - 1); + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, numSegments * 2); + for (int i = 0; i < numSegments; i++) { + f32 x = 0.5f * nw4r::math::CosRad(i * radPerSegment); + f32 z = 0.5f * nw4r::math::SinRad(i * radPerSegment); + GXPosition3f32(x, -0.5f, z); + GXPosition3f32(2.0f * x, 0.0f, 2.0f * z); + GXPosition3f32(x, 0.5f, z); + GXPosition3f32(2.0f * x, 0.0f, 2.0f * z); + } + nw4r::math::MTX34 mtx; + PSMTXTrans(mtx, 0.0f, 0.5f, 0.0f); + DrawCircleYPolygonFan(mtx, 0.0f, dat[i - DL_9]); + + PSMTXIdentity(mtx); + PSMTXRotRad(mtx, M_PI, 0x7A); + PSMTXTransApply(mtx, mtx, 0.0f, -0.5f, 0.0f); + DrawCircleYPolygonFan(mtx, 0.0f, dat[i - DL_9]); + break; + } + case DL_11: + case DL_12: { + nw4r::math::MTX34 mtx; + PSMTXIdentity(mtx); + DrawCircleYPolygonFan(mtx, 1.0f, dat[i - DL_11]); + PSMTXRotRad(mtx, M_PI, 0x7A); + DrawCircleYPolygonFan(mtx, 0.0f, dat[i - DL_11]); + break; + } + case DL_7: + case DL_8: { + nw4r::math::MTX34 mtx; + PSMTXIdentity(mtx); + PSMTXRotRad(mtx, M_PI / 2.0f, 0x78); + DrawCircleYPolygonFan(mtx, 0.0f, dat[i - DL_7]); + break; + } + + case DL_13: + case DL_14: { + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition2u8(0, 0); + if (i == DL_13) { + GXCmd1u8(0); + } + GXPosition2u8(1, 0); + if (i == DL_13) { + GXCmd1u8(1); + } + GXPosition2u8(2, 0); + if (i == DL_13) { + GXCmd1u8(2); + } + GXPosition2u8(3, 0); + if (i == DL_13) { + GXCmd1u8(3); + } + break; + } + case DL_15: + GXBegin(GX_LINESTRIP, GX_VTXFMT0, 5); + GXPosition3f32(-0.5f, 0.5f, 0.0f); + GXPosition3f32(0.5f, 0.5f, 0.0f); + GXPosition3f32(0.5f, -0.5f, 0.0f); + GXPosition3f32(-0.5f, -0.5f, 0.0f); + GXPosition3f32(0.5f, 0.5f, 0.0f); + break; + case DL_16: + case DL_17: + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXCmd1u8(0); + if (i == DL_16) { + GXCmd1u8(0); + } + GXCmd1u8(1); + if (i == DL_16) { + GXCmd1u8(1); + } + GXCmd1u8(2); + if (i == DL_16) { + GXCmd1u8(2); + } + GXCmd1u8(3); + if (i == DL_16) { + GXCmd1u8(3); + } + break; + case DL_MAX: + default: break; + } + u32 size = GXEndDisplayList(); + dl[i].mLen = size; + u8 *data = new (pHeap, 0x20) u8[(2 * size) - size]; + dl[i].mpList = data; + for (int j = 0; j < size; j++) { + data[j] = tmpDisplayList[j]; + } + DCFlushRange(data, size); + } + s_flag |= 1; +} + +void DrawGX::DrawDL(enum DL dl, const nw4r::math::MTX34 &mtx, GXColor clr) { + GXLoadPosMtxImm(mtx, 0); + GXLoadNrmMtxImm(mtx, 0); + GXSetChanMatColor(GX_COLOR0A0, clr); + GXCallDisplayList(s_DL[dl].mpList, s_DL[dl].mLen); +} + +} // namespace EGG