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
+5 -1
View File
@@ -2191,8 +2191,12 @@ egg/gfx/eggCpuTexture.cpp:
egg/gfx/eggDrawGX.cpp:
.text start:0x8049ECA0 end:0x804A0C24
.ctors start:0x804DB998 end:0x804DB99C
.rodata start:0x804FBA60 end:0x804FBC58
.data start:0x8056EDA0 end:0x8056EE60
.sdata2 start:0x8057F440 end:0x8057F584
.sdata start:0x80574F18 end:0x80574F20
.sbss start:0x80576808 end:0x80576810
.sdata2 start:0x8057F440 end:0x8057F538
.bss start:0x80674D68 end:0x80674E48
egg/gfx/eggDrawPathBase.cpp:
.text start:0x804A0C30 end:0x804A0E98
+12 -12
View File
@@ -10523,7 +10523,7 @@ __ct__11dStageMgr_cFv = .text:0x80197730; // type:function size:0x39C
fn_80197AD0 = .text:0x80197AD0; // type:function size:0x4C
fn_80197B20 = .text:0x80197B20; // type:function size:0x54
__dt__Q23EGG6ScreenFv = .text:0x80197B80; // type:function size:0x40
fn_80197BC0 = .text:0x80197BC0; // type:function size:0x40
__dt__Q23EGG7FrustumFv = .text:0x80197BC0; // type:function size:0x40
fn_80197C00 = .text:0x80197C00; // type:function size:0x64
fn_80197C70 = .text:0x80197C70; // type:function size:0x5C
__dt__22sFPhase<11dStageMgr_c>Fv = .text:0x80197CD0; // type:function size:0x58
@@ -26460,8 +26460,8 @@ BeginDrawLine__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannelQ33EGG6DrawGX5ZMode = .t
BeginDrawCircleZ__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannelQ33EGG6DrawGX5ZMode = .text:0x8049F1C0; // type:function size:0x78
BeginDrawQuad__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannelQ33EGG6DrawGX5ZModeQ33EGG6DrawGX5Blendbb = .text:0x8049F240; // type:function size:0xDC
BeginDrawScreen__Q23EGG6DrawGXFbbb = .text:0x8049F320; // type:function size:0xE0
DrawLineStrip__Q23EGG6DrawGXFPCQ23EGG8Vector3fUs7GXColorUc = .text:0x8049F400; // type:function size:0x1EC
DrawLine__Q23EGG6DrawGXFPCQ23EGG8Vector3fUs7GXColorUc = .text:0x8049F5F0; // type:function size:0x1EC
DrawLine__Q23EGG6DrawGXFPCQ23EGG8Vector3fUs8_GXColorUc = .text:0x8049F400; // type:function size:0x1EC
DrawLineStrip__Q23EGG6DrawGXFPCQ23EGG8Vector3fUs8_GXColorUc = .text:0x8049F5F0; // type:function size:0x1EC
ClearEfb__Q23EGG6DrawGXFRCQ34nw4r4math5MTX34bbb8_GXColorb = .text:0x8049F7E0; // type:function size:0x264
ResetMaterial__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannel = .text:0x8049FA50; // type:function size:0x64
SetMat_ColorChannel__Q23EGG6DrawGXFQ33EGG6DrawGX12ColorChannel = .text:0x8049FAC0; // type:function size:0xD8
@@ -26476,7 +26476,7 @@ CreateDisplayList__Q23EGG6DrawGXFPQ23EGG4Heap = .text:0x804A02E0; // type:functi
DrawDL__Q23EGG6DrawGXFQ33EGG6DrawGX2DLRCQ34nw4r4math5MTX348_GXColor = .text:0x804A0AE0; // type:function size:0x88
SetZMode__Q23EGG6DrawGXFQ33EGG6DrawGX5ZMode = .text:0x804A0B70; // type:function size:0x20
SetBlendMode__Q23EGG6DrawGXFQ33EGG6DrawGX5Blend = .text:0x804A0B90; // type:function size:0x24
DrawDLWorld__Q23EGG6DrawGXFQ33EGG6DrawGX2DLRCQ23EGG9Matrix34f7GXColor = .text:0x804A0BC0; // type:function size:0x5C
DrawDLWorld__Q23EGG6DrawGXFQ33EGG6DrawGX2DLRCQ23EGG9Matrix34f8_GXColor = .text:0x804A0BC0; // type:function size:0x5C
__sinit_\eggDrawGX_cpp = .text:0x804A0C20; // type:function size:0x4 scope:local
__ct__Q23EGG12DrawPathBaseFv = .text:0x804A0C30; // type:function size:0x58
createScnProc__Q23EGG12DrawPathBaseFP12MEMAllocator = .text:0x804A0C90; // type:function size:0x1B0
@@ -29160,9 +29160,9 @@ gRMO_Ntsc_640x456IntDf_4x3__22@unnamed@eggVideo_cpp@ = .rodata:0x804FB9BC; // ty
renderModes__3EGG = .rodata:0x804FB9F8; // type:object size:0x28 scope:local
@4804 = .rodata:0x804FBA20; // type:object size:0x10 scope:local data:4byte
copyArg2__3EGG = .rodata:0x804FBA30; // type:object size:0x18
lbl_804FBA60 = .rodata:0x804FBA60; // type:object size:0xD8
lbl_804FBB38 = .rodata:0x804FBB38; // type:object size:0x30
lbl_804FBB68 = .rodata:0x804FBB68; // type:object size:0xF0
sVtxTypes__3EGG = .rodata:0x804FBA60; // type:object size:0x10
s_ZMode__Q23EGG6DrawGX = .rodata:0x804FBB38; // type:object size:0x30
s_Blend__Q23EGG6DrawGX = .rodata:0x804FBB68; // type:object size:0xF0
lbl_804FBC58 = .rodata:0x804FBC58; // type:object size:0x18
lbl_804FBC70 = .rodata:0x804FBC70; // type:object size:0xC
lbl_804FBC7C = .rodata:0x804FBC7C; // type:object size:0xC
@@ -39824,7 +39824,7 @@ sWPADWorkSize__Q23EGG17CoreControllerMgr = .sdata:0x80574EE8; // type:object siz
@3877 = .sdata:0x80574F00; // type:object size:0x8 scope:local data:string
@3879 = .sdata:0x80574F08; // type:object size:0x8 scope:local data:string
@3880 = .sdata:0x80574F10; // type:object size:0x7 scope:local data:string
EGG__DrawGX__sLightMaskDefault = .sdata:0x80574F18; // type:object size:0x8 data:4byte
sLightMaskDefault__Q23EGG6DrawGX = .sdata:0x80574F18; // type:object size:0x4 data:4byte
lbl_80574F20 = .sdata:0x80574F20; // type:object size:0x8
lbl_80574F28 = .sdata:0x80574F28; // type:object size:0x4
lbl_80574F2C = .sdata:0x80574F2C; // type:object size:0x4 data:4byte
@@ -41148,7 +41148,7 @@ sPtrOverride__Q23EGG6Assert = .sbss:0x80576800; // type:object size:0x4 data:4by
sInstantHalt__Q23EGG6Assert = .sbss:0x80576804; // type:object size:0x1 data:byte
sAssertOccurred__Q23EGG6Assert = .sbss:0x80576805; // type:object size:0x1 data:byte
s_flag__Q23EGG6DrawGX = .sbss:0x80576808; // type:object size:0x4 data:4byte
EGG__DrawGX__sTexMapDefault = .sbss:0x8057680C; // type:object size:0x4 data:4byte
sTexMapDefault__Q23EGG6DrawGX = .sbss:0x8057680C; // type:object size:0x4 data:4byte
EGG__Frustum__sGlobalScale = .sbss:0x80576810; // type:object size:0x4 data:float
EGG__Frustum__sGlobalOffset = .sbss:0x80576818; // type:object size:0x4 data:float
lbl_80576820 = .sbss:0x80576820; // type:object size:0x1 data:byte
@@ -48020,7 +48020,7 @@ BLACK__Q23EGG6DrawGX = .sdata2:0x8057F440; // type:object size:0x4 data:4byte
WHITE__Q23EGG6DrawGX = .sdata2:0x8057F444; // type:object size:0x4 data:4byte
RED__Q23EGG6DrawGX = .sdata2:0x8057F448; // type:object size:0x4 data:4byte
GREEN__Q23EGG6DrawGX = .sdata2:0x8057F44C; // type:object size:0x4 data:4byte
BLUE__Q23EGG6DrawGX = .sdata2:0x8057F450; // type:object size:0x8 data:4byte
BLUE__Q23EGG6DrawGX = .sdata2:0x8057F450; // type:object size:0x4 data:4byte
lbl_8057F458 = .sdata2:0x8057F458; // type:object size:0x8 data:4byte
lbl_8057F460 = .sdata2:0x8057F460; // type:object size:0x4 data:float
lbl_8057F464 = .sdata2:0x8057F464; // type:object size:0x4 data:float
@@ -49798,8 +49798,8 @@ ey__Q23EGG8Vector3f = .bss:0x80674C48; // type:object size:0xC data:float
ez__Q23EGG8Vector3f = .bss:0x80674C54; // type:object size:0xC data:float
buf__Q23EGG6Assert = .bss:0x80674C60; // type:object size:0x104
s_DL__Q23EGG6DrawGX = .bss:0x80674D68; // type:object size:0x90
sCameraMtx = .bss:0x80674DF8; // type:object size:0x30 data:float
lbl_80674E28 = .bss:0x80674E28; // type:object size:0x20
s_cameraMtx__Q23EGG6DrawGX = .bss:0x80674DF8; // type:object size:0x30 data:float
sDummyTexObj__Q23EGG6DrawGX = .bss:0x80674E28; // type:object size:0x20
sMtx__Q23EGG15GlobalDrawState = .bss:0x80674E48; // type:object size:0x30
CPU_TEX_ARR = .bss:0x80674E78; // type:object size:0x48 data:4byte
sMtx__3EGG = .bss:0x80674EC0; // type:object size:0x30 data:float
+80 -3
View File
@@ -5,6 +5,10 @@
#include "egg/core/eggHeap.h"
#include "egg/gfx/eggTexture.h"
#include "egg/math/eggMatrix.h"
#include "nw4r/g3d/res/g3d_restex.h"
#include "nw4r/math/math_types.h"
#include "rvl/GX/GXTexture.h"
#include "rvl/GX/GXTypes.h"
#include "rvl/GX.h" // IWYU pragma: export
@@ -12,12 +16,28 @@ namespace EGG {
class DrawGX {
public:
DrawGX() {}
// made up
struct DLData {
u8 *mpList;
u32 mLen;
};
// made up, stride 0xC
struct ZModeConfig {
bool mTest;
GXCompare mCompare;
bool mUpdate;
};
// made up, stride 0x10
struct BlendModeConfig {
GXBlendMode mBlendMode;
GXBlendFactor mBlendFactorSrc;
GXBlendFactor mBlendFactorDst;
GXLogicOp mLogicOp;
};
enum DL {
DL_0,
DL_1,
@@ -78,21 +98,78 @@ public:
BLEND_MAX
};
enum ZMode {
ZMODE_0,
ZMODE_1,
ZMODE_2,
ZMODE_3,
ZMODE_MAX,
};
enum TevSetting {
TEV_0,
TEV_1,
TEV_2,
};
enum TexGen {
TEXGEN_0,
TEXGEN_1,
};
enum ColorChannel {
COLORCHAN_0,
COLORCHAN_1,
};
static void Initialize(Heap *);
static GXTexMapID GetTexMapDefault();
static void LoadTexture(const EGG::ResTIMG *, GXTexMapID);
static GXLightID GetLightMaskDefault();
static void BeginDrawLine(ColorChannel, ZMode);
static void BeginDrawCircleZ(ColorChannel, ZMode);
static void BeginDrawQuad(ColorChannel, ZMode, Blend, bool, bool);
static void BeginDrawScreen(bool, bool, bool);
static void CreateDisplayList(EGG::Heap*);
static void DrawLineStrip(const EGG::Vector3f *, u16, GXColor, u8);
static void DrawLine(const EGG::Vector3f *, u16, GXColor, u8);
static void ClearEfb(const nw4r::math::MTX34 &, bool, bool, bool, GXColor, bool);
static void ResetMaterial(enum ColorChannel);
static void SetMat_ColorChannel(enum ColorChannel);
static void SetMat_TexGen(enum TexGen);
static void SetMat_Ind();
static void SetMat_Tev(GXTevStageID, enum TevSetting);
static void SetMat_PE(enum ZMode, enum Blend);
static void LoadTexture(const EGG::ResTIMG *, GXTexMapID);
static void LoadTexture(nw4r::g3d::ResTex, GXTexMapID);
static void CreateDisplayList(EGG::Heap *);
static void DrawDL(enum DL, const nw4r::math::MTX34 &, GXColor);
static void SetVtxState(enum VtxType);
static void SetZMode(enum ZMode);
static void SetBlendMode(enum Blend);
static void DrawDLWorld(DL dl, const EGG::Matrix34f& mtx, GXColor color);
// TODO MORE
// not sure
static DLData s_DL[DL_MAX];
static const DL s_DL0;
static const DL s_DL7;
static const DL s_DL8;
static Matrix34f s_cameraMtx;
static const ZModeConfig s_ZMode[ZMODE_MAX];
static const BlendModeConfig s_Blend[BLEND_MAX];
static GXTexObj sDummyTexObj;
// not sure end
static GXTexMapID sTexMapDefault;
static GXLightID sLightMaskDefault;
static nw4r::math::MTX34 s_cameraMtx;
static u32 s_flag;
+14 -1
View File
@@ -1,6 +1,19 @@
#ifndef EGG_GX_UTILITY_H
#define EGG_GX_UTILITY_H
namespace EGG {} // namespace EGG
#include "egg/gfx/eggTexture.h"
#include "nw4r/g3d/res/g3d_restex.h"
#include "rvl/GX/GXTexture.h"
namespace EGG {
class GXUtility {
public:
static int getTexMtxID(int);
static void getTexObj(GXTexObj *, const EGG::ResTIMG &);
static void getTexObj(_GXTexObj *, nw4r::g3d::ResTex, GXTexWrapMode, GXTexWrapMode, GXTexFilter, GXTexFilter);
};
} // namespace EGG
#endif
+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