DrawGX almost completely matching

This commit is contained in:
robojumper
2025-03-19 00:27:22 +01:00
parent aa9d6c1557
commit 1661ab219f
5 changed files with 594 additions and 21 deletions
+483 -4
View File
@@ -1,13 +1,21 @@
#include "egg/gfx/eggDrawGX.h"
#include "common.h"
#include "egg/gfx/eggGXUtility.h"
#include "egg/gfx/eggStateGX.h"
#include "math.h"
#include "nw4r/g3d/res/g3d_restex.h"
#include "nw4r/math/math_triangular.h"
#include "nw4r/math/math_types.h"
#include "rvl/GX/GXAttr.h"
#include "rvl/GX/GXBump.h"
#include "rvl/GX/GXDisplayList.h"
#include "rvl/GX/GXDraw.h"
#include "rvl/GX/GXGeometry.h"
#include "rvl/GX/GXLight.h"
#include "rvl/GX/GXPixel.h"
#include "rvl/GX/GXTev.h"
#include "rvl/GX/GXTexture.h"
#include "rvl/GX/GXTransform.h"
#include "rvl/GX/GXTypes.h"
#include "rvl/GX/GXVert.h"
@@ -16,6 +24,29 @@
#include "rvl/MTX/vec.h"
#include "rvl/OS/OSCache.h"
namespace EGG {
const GXColor DrawGX::BLACK = {0x00, 0x00, 0x00, 0xFF};
const GXColor DrawGX::WHITE = {0xFF, 0xFF, 0xFF, 0xFF};
const GXColor DrawGX::RED = {0xFF, 0x00, 0x00, 0xFF};
const GXColor DrawGX::GREEN = {0x00, 0xFF, 0x00, 0xFF};
const GXColor DrawGX::BLUE = {0x00, 0x00, 0xFF, 0xFF};
const DrawGX::DL DrawGX::s_DL0 = DrawGX::DL_0;
const DrawGX::DL DrawGX::s_DL7 = DrawGX::DL_7;
const DrawGX::DL DrawGX::s_DL8 = DrawGX::DL_8;
GXTexMapID DrawGX::sTexMapDefault;
GXLightID DrawGX::sLightMaskDefault = GX_LIGHT0;
nw4r::math::MTX34 DrawGX::s_cameraMtx;
DrawGX::DLData DrawGX::s_DL[DL_MAX];
GXTexObj DrawGX::sDummyTexObj;
u32 DrawGX::s_flag;
}; // namespace EGG
namespace {
static void DrawQuadNormal(u8 x1, u8 x2, u8 x3, u8 x4, u8 y) {
@@ -35,10 +66,10 @@ static void DrawQuadLineStripNormal(u8 x1, u8 x2, u8 x3, u8 x4, u8 y) {
}
static void DrawCircleYPolygonFan(const nw4r::math::MTX34 &mtx, f32 f, u16 numSegments) {
f32 stepSize = (2.0f * M_PI / numSegments);
nw4r::math::VEC3 v1(0.0f, 1.0f, 0.0f);
nw4r::math::VEC3 v2(0.0f, f, 0.0f);
f32 stepSize = (2.0f * M_PI / numSegments);
int seg = numSegments + 1;
PSMTXMultVec(mtx, v1, v1);
@@ -70,8 +101,8 @@ static void DrawCircleYPolygonFan(const nw4r::math::MTX34 &mtx, f32 f, u16 numSe
PSMTXMultVec(mtx, v4, v4);
PSMTXMultVec(mtx, v5, v5);
v4 -= v2;
v5 -= v2;
nw4r::math::VEC3Sub(&v4, &v4, &v2);
nw4r::math::VEC3Sub(&v5, &v5, &v2);
nw4r::math::VEC3 v6;
PSVECCrossProduct(v5, v4, v6);
@@ -85,7 +116,413 @@ static void DrawCircleYPolygonFan(const nw4r::math::MTX34 &mtx, f32 f, u16 numSe
namespace EGG {
u8 sDetailLevels[] = {10, 20};
static DrawGX sDrawGX;
static u8 DummyTextureData[64] = {
// clang-format off
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
};
void DrawGX::Initialize(Heap *pHeap_) {
2.0f; // cool
Heap *pHeap = pHeap_ == nullptr ? Heap::getCurrentHeap() : pHeap_;
GXInitTexObj(&sDummyTexObj, DummyTextureData, 4, 4, GX_TF_Z24X8, GX_REPEAT, GX_REPEAT, false);
GXInitTexObjLOD(&sDummyTexObj, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, 0, 0, GX_ANISO_1);
PSMTXIdentity(s_cameraMtx.m);
CreateDisplayList(pHeap);
}
GXTexMapID DrawGX::GetTexMapDefault() {
return sTexMapDefault;
}
GXLightID DrawGX::GetLightMaskDefault() {
return sLightMaskDefault;
}
void DrawGX::BeginDrawLine(ColorChannel chan, ZMode zMode) {
SetMat_ColorChannel(chan);
SetMat_TexGen(TEXGEN_0);
SetMat_Ind();
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
GXSetNumTevStages(1);
SetMat_Tev(GX_TEVSTAGE0, TEV_0);
SetMat_PE(zMode, BLEND_0);
SetVtxState(VTX_TYPE_1);
}
void DrawGX::BeginDrawCircleZ(ColorChannel chan, ZMode zMode) {
SetMat_ColorChannel(chan);
SetMat_TexGen(TEXGEN_0);
SetMat_Ind();
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
GXSetNumTevStages(1);
SetMat_Tev(GX_TEVSTAGE0, TEV_0);
SetMat_PE(zMode, BLEND_0);
SetVtxState(VTX_TYPE_4);
}
void DrawGX::BeginDrawQuad(ColorChannel chan, ZMode zMode, Blend blendMode, bool b1, bool b2) {
SetMat_ColorChannel(chan);
SetMat_TexGen(b1 ? TEXGEN_1 : TEXGEN_0);
SetMat_Ind();
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
GXSetNumTevStages(1);
SetMat_Tev(GX_TEVSTAGE0, b1 ? TEV_2 : TEV_0);
if (b2) {
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA);
}
SetMat_PE(zMode, blendMode);
SetVtxState(b1 ? VTX_TYPE_7 : VTX_TYPE_8);
}
static const DrawGX::VtxType sVtxTypes[2][2] = {
{DrawGX::VTX_TYPE_10, DrawGX::VTX_TYPE_12},
{DrawGX::VTX_TYPE_11, DrawGX::VTX_TYPE_13},
};
void DrawGX::BeginDrawScreen(bool b1, bool b2, bool b3) {
SetMat_ColorChannel(COLORCHAN_1);
SetMat_TexGen(b2 ? TEXGEN_1 : TEXGEN_0);
SetMat_Ind();
GXSetNumTevStages(1);
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
SetMat_Tev(GX_TEVSTAGE0, b2 ? TEV_2 : TEV_0);
if (b3) {
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA);
}
SetMat_PE(ZMODE_0, BLEND_0);
SetVtxState(sVtxTypes[b1 ? 1 : 0][b2 ? 0 : 1]);
}
void DrawGX::DrawLine(const EGG::Vector3f *pPoints, u16 numPoints, GXColor color, u8 thickness) {
GXLoadPosMtxImm(s_cameraMtx.m, 0);
GXSetChanMatColor(GX_COLOR0A0, color);
GXSetLineWidth(thickness, 0);
GXBegin(GX_LINES, GX_VTXFMT0, numPoints);
for (int i = 0; i < numPoints; i++) {
GXPosition3f32(pPoints[i].x, pPoints[i].y, pPoints[i].z);
}
}
void DrawGX::DrawLineStrip(const EGG::Vector3f *pPoints, u16 numPoints, GXColor color, u8 thickness) {
GXLoadPosMtxImm(s_cameraMtx.m, 0);
GXSetChanMatColor(GX_COLOR0A0, color);
GXSetLineWidth(thickness, 0);
GXBegin(GX_LINESTRIP, GX_VTXFMT0, numPoints);
for (int i = 0; i < numPoints; i++) {
GXPosition3f32(pPoints[i].x, pPoints[i].y, pPoints[i].z);
}
}
void DrawGX::ClearEfb(
const nw4r::math::MTX34 &mat, bool bColorUpdate, bool bAlphaUpdate, bool b3, GXColor clr, bool b4
) {
StateGX::ScopedColor colorUpdate(bColorUpdate);
StateGX::ScopedAlpha alphaUpdate(bAlphaUpdate);
SetMat_ColorChannel(COLORCHAN_1);
GXSetCullMode(GX_CULL_NONE);
if (b3) {
SetMat_TexGen(TEXGEN_1);
GXLoadTexObj(&sDummyTexObj, sTexMapDefault);
} else {
SetMat_TexGen(TEXGEN_0);
}
SetMat_Ind();
GXSetNumTevStages(1);
GXSetTevDirect(GX_TEVSTAGE0);
GXSetTevColor(GX_TEVREG0, clr);
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
if (b3) {
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, sTexMapDefault, GX_COLOR_NULL);
} else {
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, 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_CS_SCALE_1, 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_CS_SCALE_1, true, GX_TEVPREV);
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
SetBlendMode(BLEND_14);
if (b3) {
GXSetZTexture(2, GX_TF_Z24X8, 0);
SetZMode(ZMODE_3);
GXSetZCompLoc(0);
SetVtxState(b4 ? VTX_TYPE_11 : VTX_TYPE_10);
GXLoadPosMtxImm(mat, 0);
GXCallDisplayList(s_DL[DL_16].mpList, s_DL[DL_16].mLen);
GXSetZTexture(0, GX_TF_Z24X8, 0);
GXSetZCompLoc(1);
} else {
SetZMode(ZMODE_0);
SetVtxState(b4 ? VTX_TYPE_13 : VTX_TYPE_12);
GXLoadPosMtxImm(mat, 0);
GXCallDisplayList(s_DL[DL_17].mpList, s_DL[DL_17].mLen);
}
}
void DrawGX::ResetMaterial(enum ColorChannel chan) {
SetMat_ColorChannel(chan);
SetMat_TexGen(TEXGEN_0);
SetMat_Ind();
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
GXSetNumTevStages(1);
SetMat_Tev(GX_TEVSTAGE0, TEV_0);
SetMat_PE(ZMODE_1, BLEND_0);
}
void DrawGX::SetMat_ColorChannel(enum ColorChannel chan) {
switch (chan) {
case COLORCHAN_0:
GXSetNumChans(1);
GXSetCullMode(GX_CULL_BACK);
GXSetChanCtrl(GX_COLOR0A0, true, GX_SRC_REG, GX_SRC_REG, GetLightMaskDefault(), GX_DF_CLAMP, GX_AF_SPOT);
GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
break;
case COLORCHAN_1:
GXSetNumChans(1);
GXSetCullMode(GX_CULL_BACK);
GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_SPOT);
GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
break;
}
}
void DrawGX::SetMat_TexGen(enum TexGen texGen) {
switch (texGen) {
case TEXGEN_0:
GXSetNumTexGens(0);
GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d);
break;
case TEXGEN_1:
GXSetNumTexGens(1);
GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d);
break;
}
}
void DrawGX::SetMat_Ind() {
GXSetNumIndStages(0);
}
void DrawGX::SetMat_Tev(GXTevStageID stageId, enum TevSetting setting) {
switch (setting) {
case TEV_0:
GXSetTevDirect(stageId);
GXSetTevOrder(stageId, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
GXSetTevSwapMode(stageId, GX_TEV_SWAP0, GX_TEV_SWAP0);
GXSetTevColorIn(stageId, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC);
GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GXSetTevAlphaIn(stageId, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA);
GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV);
break;
case TEV_2:
GXSetTevDirect(stageId);
GXSetTevOrder(stageId, GX_TEXCOORD0, sTexMapDefault, GX_COLOR0A0);
GXSetTevSwapMode(stageId, GX_TEV_SWAP0, GX_TEV_SWAP0);
GXSetTevColorIn(stageId, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO);
GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GXSetTevAlphaIn(stageId, GX_CA_ZERO, GX_CA_TEXA, GX_CA_RASA, GX_CA_ZERO);
GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV);
break;
case TEV_1:
GXSetTevDirect(stageId);
GXSetTevOrder(stageId, GX_TEXCOORD0, sTexMapDefault, GX_COLOR0A0);
GXSetTevSwapMode(stageId, GX_TEV_SWAP0, GX_TEV_SWAP0);
GXSetTevColorIn(stageId, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC);
GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV);
GXSetTevAlphaIn(stageId, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA);
GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV);
break;
}
}
void DrawGX::SetMat_PE(enum ZMode zMode, enum Blend blendMode) {
GXSetZCompLoc(true);
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
SetZMode(zMode);
SetBlendMode(blendMode);
}
void DrawGX::LoadTexture(const EGG::ResTIMG *tex, GXTexMapID texMapId) {
GXTexObj obj;
GXUtility::getTexObj(&obj, *tex);
GXLoadTexObj(&obj, texMapId);
}
void DrawGX::LoadTexture(nw4r::g3d::ResTex tex, GXTexMapID texMapId) {
GXTexObj obj;
GXUtility::getTexObj(&obj, tex, GX_CLAMP, GX_CLAMP, GX_LINEAR, GX_LINEAR);
GXLoadTexObj(&obj, texMapId);
}
void DrawGX::SetVtxState(EGG::DrawGX::VtxType type) {
GXClearVtxDesc();
switch (type) {
case VTX_TYPE_0:
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0xe);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_RGBA4, 0xe);
// clang-format off
static const ALIGN_DECL(32) u8 sVtxDataType0[] = {
0xE0, 0x00, 0x20, 0x00,
0xE0, 0x00, 0xE0, 0x00,
0x20, 0x00, 0x20, 0x00,
0x20, 0x00, 0x20, 0x00,
0x20, 0x00, 0x20, 0x00,
0x20, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0x20, 0x00,
0x20, 0x00, 0xE0, 0x00,
0x20, 0x00, 0x20, 0x00,
0xE0, 0x00, 0xE0, 0x00,
};
static const ALIGN_DECL(32) u8 sNrmDataType0[] = {
0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0xC0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00,
};
// clang-format on
GXSetArray(GX_VA_POS, sVtxDataType0, 6);
GXSetArray(GX_VA_NRM, sNrmDataType0, 6);
GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
break;
case VTX_TYPE_2:
case VTX_TYPE_3:
case VTX_TYPE_4:
case VTX_TYPE_5:
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_F32, 0);
break;
case VTX_TYPE_6:
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
break;
case VTX_TYPE_1:
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
break;
case VTX_TYPE_7:
case VTX_TYPE_8:
// clang-format off
static const ALIGN_DECL(32) u8 sVtxDataType7[] = {
0xE0, 0x00, 0x20, 0x00,
0x20, 0x00, 0x20, 0x00,
0x20, 0x00, 0xE0, 0x00,
0xE0, 0x00, 0xE0, 0x00,
};
static const ALIGN_DECL(32) u8 sNrmDataType7[] = {
0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00,
};
static const ALIGN_DECL(32) u8 sTexDataType7[] = {
0x00, 0x00, 0x01, 0x00,
0x01, 0x01, 0x00, 0x01,
};
// clang-format on
GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
if (type == VTX_TYPE_7) {
GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
}
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGBA4, 0xe);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_RGBA4, 0xe);
if (type == VTX_TYPE_7) {
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGB565, 0);
}
GXSetArray(GX_VA_POS, sVtxDataType7, 4);
GXSetArray(GX_VA_NRM, sNrmDataType7, 6);
if (type == VTX_TYPE_7) {
GXSetArray(GX_VA_TEX0, sTexDataType7, 2);
}
break;
case VTX_TYPE_9:
// clang-format off
static const ALIGN_DECL(32) u8 sVtxDataType9[] = {
0xE0, 0x00, 0x00, 0x00,
0xE0, 0x00, 0x20, 0x00,
0x00, 0x00, 0xE0, 0x00,
0x20, 0x00, 0x00, 0x00,
0x20, 0x00, 0xE0, 0x00,
0x00, 0x00, 0x20, 0x00,
};
static const ALIGN_DECL(32) u8 sNrmDataType9[] = {
0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00,
};
// clang-format on
GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0xe);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_RGBA4, 0xe);
GXSetArray(GX_VA_POS, sVtxDataType9, 6);
GXSetArray(GX_VA_NRM, sNrmDataType9, 6);
break;
case VTX_TYPE_10:
case VTX_TYPE_11:
case VTX_TYPE_12:
case VTX_TYPE_13: {
// clang-format off
static const ALIGN_DECL(32) u8 sPosDataType10[] = {
0x00, 0x01, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00,
};
static const ALIGN_DECL(32) u8 sTexDataType10[] = {
0x00, 0x00, 0x01, 0x00,
0x01, 0x01, 0x00, 0x01,
};
// clang-format on
bool bVar1 = type == VTX_TYPE_11 || type == VTX_TYPE_13;
bool bVar2 = type == VTX_TYPE_10 || type == VTX_TYPE_11;
GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
if (bVar2) {
GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
}
GXSetArray(GX_VA_POS, bVar1 ? sTexDataType10 : sPosDataType10, 2);
if (bVar2) {
GXSetArray(GX_VA_TEX0, sTexDataType10, 2);
}
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGB565, 0);
if (bVar2) {
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGB565, 0);
}
break;
}
}
}
const u8 sDetailLevels[] = {0x10, 0x20};
void DrawGX::CreateDisplayList(EGG::Heap *pHeap) {
u8 ALIGN_DECL(32) tmpDisplayList[16 * 1024];
@@ -251,4 +688,46 @@ void DrawGX::DrawDL(enum DL dl, const nw4r::math::MTX34 &mtx, GXColor clr) {
GXCallDisplayList(s_DL[dl].mpList, s_DL[dl].mLen);
}
const DrawGX::ZModeConfig DrawGX::s_ZMode[ZMODE_MAX] = {
{false, GX_ALWAYS, false},
{ true, GX_LEQUAL, true},
{ true, GX_LEQUAL, false},
{ true, GX_ALWAYS, true},
};
void DrawGX::SetZMode(enum ZMode mode) {
GXSetZMode(s_ZMode[mode].mTest, s_ZMode[mode].mCompare, s_ZMode[mode].mUpdate);
}
const DrawGX::BlendModeConfig DrawGX::s_Blend[BLEND_MAX] = {
{ GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_INVSRCALPHA, GX_BL_SRCALPHA, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_SRCCLR, GX_BL_ONE, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_INVSRCCLR, GX_BL_ONE, GX_LO_CLEAR},
{GX_BM_SUBTRACT, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_ZERO, GX_BL_SRCCLR, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_ZERO, GX_BL_INVSRCCLR, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_DSTALPHA, GX_BL_INVDSTALPHA, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_INVDSTALPHA, GX_BL_DSTALPHA, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_DSTALPHA, GX_BL_ONE, GX_LO_CLEAR},
{ GX_BM_BLEND, GX_BL_INVDSTALPHA, GX_BL_ONE, GX_LO_CLEAR},
{ GX_BM_NONE, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR},
};
void DrawGX::SetBlendMode(enum Blend mode) {
GXSetBlendMode(
s_Blend[mode].mBlendMode, s_Blend[mode].mBlendFactorSrc, s_Blend[mode].mBlendFactorDst, s_Blend[mode].mLogicOp
);
}
void DrawGX::DrawDLWorld(DL dl, const EGG::Matrix34f &mtx, GXColor color) {
nw4r::math::MTX34 resMtx;
PSMTXConcat(s_cameraMtx.m, mtx.m, resMtx.m);
DrawDL(dl, resMtx, color);
}
} // namespace EGG