From 2c2d5849b4f64e5938ab7108d263ffad5d24962f Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 20 Mar 2025 19:46:28 +0100 Subject: [PATCH] More effect --- config/SOUE01/splits.txt | 3 + config/SOUE01/symbols.txt | 14 +-- include/egg/gfx/eggPostEffectBase.h | 2 +- include/egg/gfx/eggPostEffectBlur.h | 4 +- include/egg/gfx/eggPostEffectUnk1.h | 6 +- include/egg/gfx/eggPostEffectUnk2.h | 28 ++++- src/egg/gfx/eggPostEffectBase.cpp | 1 + src/egg/gfx/eggPostEffectBlur.cpp | 3 +- src/egg/gfx/eggPostEffectUnk1.cpp | 2 +- src/egg/gfx/eggPostEffectUnk2.cpp | 187 +++++++++++++++++++++++++++- 10 files changed, 233 insertions(+), 17 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 724250f1..f491642c 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2290,6 +2290,9 @@ egg/gfx/eggPostEffectUnk1.cpp: egg/gfx/eggPostEffectUnk2.cpp: .text start:0x804B00A0 end:0x804B0AA4 + .rodata start:0x804FBD50 end:0x804FBD88 + .data start:0x8056F1B0 end:0x8056F1D0 + .sdata2 start:0x8057F798 end:0x8057F7C8 egg/gfx/eggPostEffectMask.cpp: .text start:0x804B0AB0 end:0x804B0F60 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 1ca9a08a..c6466bab 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26403,7 +26403,7 @@ setAssertCallback__Q23EGG6AssertFPFv_v = .text:0x8049C180; // type:function size system_halt__Q23EGG6AssertFPCcUlPCcP16__va_list_struct = .text:0x8049C190; // type:function size:0x398 assert__Q23EGG6AssertFPCcUlPCce = .text:0x8049C530; // type:function size:0x8C updateMatrix__Q23EGG10BaseCameraFv = .text:0x8049C5C0; // type:function size:0x10 -draw__Q23EGG10BaseCameraFv = .text:0x8049C5D0; // type:function size:0x50 +draw__Q23EGG10BaseCameraFPQ23EGG10BaseCamera = .text:0x8049C5D0; // type:function size:0x50 setG3DCamera__Q23EGG10BaseCameraFRQ34nw4r3g3d6Camera = .text:0x8049C620; // type:function size:0x44 getViewMatrixOld__Q23EGG12LookAtCameraFv = .text:0x8049C670; // type:function size:0x8 doUpdateMatrix__Q23EGG12LookAtCameraFv = .text:0x8049C680; // type:function size:0x25C @@ -26413,7 +26413,7 @@ loadOldMatrix__Q23EGG12LookAtCameraFv = .text:0x8049C940; // type:function size: __ct__Q23EGG11OrthoCameraFv = .text:0x8049C950; // type:function size:0x78 update_parms__Q23EGG11OrthoCameraFv = .text:0x8049C9D0; // type:function size:0x88 doUpdateMatrix__Q23EGG11OrthoCameraFv = .text:0x8049CA60; // type:function size:0x34 -getPosition__Q23EGG12LookAtCameraCFv = .text:0x8049CAA0; // type:function size:0x1C +getPosition__Q23EGG12LookAtCameraFv = .text:0x8049CAA0; // type:function size:0x1C getViewMatrix__Q23EGG12LookAtCameraCFv = .text:0x8049CAC0; // type:function size:0x8 storeTLUT__Q23EGG7PaletteF7_GXTlut10_GXTlutFmtQ23EGG15JUTTransparencyUsPv = .text:0x8049CAD0; // type:function size:0x24 load__Q23EGG7PaletteFv = .text:0x8049CB00; // type:function size:0x44 @@ -26707,10 +26707,10 @@ draw__Q23EGG14PostEffectBlurFff = .text:0x804AF5A0; // type:function size:0x190 drawInternal__Q23EGG14PostEffectBlurFUcUcff = .text:0x804AF730; // type:function size:0x4D4 __ct__Q23EGG14PostEffectUnk1Fv = .text:0x804AFC10; // type:function size:0xC0 setMaterialInternal__Q23EGG14PostEffectUnk1Fv = .text:0x804AFCD0; // type:function size:0x3C8 -FUN_804b00a0 = .text:0x804B00A0; // type:function size:0x1F8 -FUN_804b02a0 = .text:0x804B02A0; // type:function size:0x80 -FUN_804b0320 = .text:0x804B0320; // type:function size:0x2D4 -FUN_804b0600 = .text:0x804B0600; // type:function size:0x4A4 +__ct__Q23EGG14PostEffectUnk2Fv = .text:0x804B00A0; // type:function size:0x1F8 +__dt__Q23EGG14PostEffectUnk2Fv = .text:0x804B02A0; // type:function size:0x80 +draw__Q23EGG14PostEffectUnk2Fff = .text:0x804B0320; // type:function size:0x2D4 +setMaterialInternal__Q23EGG14PostEffectUnk2Fv = .text:0x804B0600; // type:function size:0x4A4 __ct__Q23EGG14PostEffectMaskFv = .text:0x804B0AB0; // type:function size:0x64 setMaterialInternal__Q23EGG14PostEffectMaskFv = .text:0x804B0B20; // type:function size:0x440 FUN_804b0f60 = .text:0x804B0F60; // type:function size:0x160 @@ -37378,7 +37378,7 @@ jumptable_8056F120 = .data:0x8056F120; // type:object size:0x30 scope:local __vt__Q23EGG14PostEffectBase = .data:0x8056F150; // type:object size:0x1C __vt__Q23EGG14PostEffectBlur = .data:0x8056F170; // type:object size:0x1C __vt__Q23EGG14PostEffectUnk1 = .data:0x8056F190; // type:object size:0x20 -lbl_8056F1B0 = .data:0x8056F1B0; // type:object size:0x20 +__vt__Q23EGG14PostEffectUnk2 = .data:0x8056F1B0; // type:object size:0x1C __vt__Q23EGG14PostEffectMask = .data:0x8056F1D0; // type:object size:0x1C lbl_8056F1F0 = .data:0x8056F1F0; // type:object size:0x20 lbl_8056F210 = .data:0x8056F210; // type:object size:0x20 diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index 16a036f1..2c3207ed 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -3,7 +3,7 @@ #include "common.h" #include "egg/egg_types.h" -#include "egg/gfx/eggCapTexture.h" +#include "nw4r/math/math_types.h" #include "rvl/GX/GXTypes.h" namespace EGG { diff --git a/include/egg/gfx/eggPostEffectBlur.h b/include/egg/gfx/eggPostEffectBlur.h index 02459743..62b6625e 100644 --- a/include/egg/gfx/eggPostEffectBlur.h +++ b/include/egg/gfx/eggPostEffectBlur.h @@ -8,7 +8,7 @@ namespace EGG { class PostEffectBlur : PostEffectBase { - struct Kernel { + struct Stage { /* 0x00 */ u8 field_0x00; /* 0x01 */ GXColor field_0x01; /* 0x08 */ f32 field_0x08; @@ -38,7 +38,7 @@ private: /* 0x2C */ u8 field_0x2C; /* 0x30 */ f32 field_0x30; /* 0x34 */ f32 field_0x34; - /* 0x38 */ Kernel field_0x38[4]; + /* 0x38 */ Stage field_0x38[4]; }; } // namespace EGG diff --git a/include/egg/gfx/eggPostEffectUnk1.h b/include/egg/gfx/eggPostEffectUnk1.h index 2d93e9be..e2a6c03b 100644 --- a/include/egg/gfx/eggPostEffectUnk1.h +++ b/include/egg/gfx/eggPostEffectUnk1.h @@ -8,22 +8,22 @@ namespace EGG { class PostEffectUnk1 : public PostEffectBase { // Size 0x18 - struct Kernel { + struct Stage { /* 0x00 */ EGG::CpuTexture *field_0x00; /* 0x04 */ GXTexMapID mTexMapId; /* 0x08 */ GXColor field_0x08; /* 0x0C */ f32 field_0x0C; /* 0x10 */ u8 field_0x10; }; + public: PostEffectUnk1(); virtual void setMaterialInternal() override; - /* 0x2C */ u8 field_0x2C; /* 0x2D */ u8 field_0x2D; /* 0x30 */ f32 field_0x30; - /* 0x34 */ Kernel field_0x34[3]; + /* 0x34 */ Stage field_0x34[3]; }; } // namespace EGG diff --git a/include/egg/gfx/eggPostEffectUnk2.h b/include/egg/gfx/eggPostEffectUnk2.h index 2e324f7a..64173db6 100644 --- a/include/egg/gfx/eggPostEffectUnk2.h +++ b/include/egg/gfx/eggPostEffectUnk2.h @@ -1,6 +1,32 @@ #ifndef EGG_POST_EFFECT_UNK2_H #define EGG_POST_EFFECT_UNK2_H -namespace EGG {} // namespace EGG +#include "egg/egg_types.h" +#include "egg/gfx/eggPostEffectBase.h" + +namespace EGG { + +class PostEffectUnk2 : public PostEffectBase { +public: + PostEffectUnk2(); + virtual ~PostEffectUnk2(); + virtual void draw(f32 width, f32 height) override; + virtual void setMaterialInternal() override; + +private: + /* 0x2C */ s32 field_0x2C; + /* 0x30 */ u32 field_0x30; + /* 0x34 */ u8 field_0x34; + /* 0x35 */ u8 field_0x35; + /* 0x36 */ s16 field_0x36; + /* 0x38 */ f32 field_0x38; + /* 0x3C */ f32 field_0x3C; + /* 0x40 */ f32 field_0x40; + /* 0x44 */ f32 field_0x44; + /* 0x48 */ f32 field_0x48; + /* 0x4C */ EGG::CpuTexture *mpTexture; +}; + +} // namespace EGG #endif diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp index 2c93e001..9ecead4a 100644 --- a/src/egg/gfx/eggPostEffectBase.cpp +++ b/src/egg/gfx/eggPostEffectBase.cpp @@ -3,6 +3,7 @@ #include "common.h" #include "egg/gfx/eggDrawGX.h" #include "egg/gfx/eggScreen.h" +#include "egg/gfx/eggCapTexture.h" #include "egg/math/eggVector.h" #include "math.h" #include "nw4r/math/math_triangular.h" diff --git a/src/egg/gfx/eggPostEffectBlur.cpp b/src/egg/gfx/eggPostEffectBlur.cpp index 3fd180f9..13dfad93 100644 --- a/src/egg/gfx/eggPostEffectBlur.cpp +++ b/src/egg/gfx/eggPostEffectBlur.cpp @@ -1,6 +1,7 @@ #include "egg/gfx/eggPostEffectBlur.h" #include "common.h" +#include "egg/gfx/eggCapTexture.h" #include "egg/gfx/eggDrawGX.h" #include "egg/gfx/eggGXUtility.h" #include "math.h" @@ -49,7 +50,7 @@ void PostEffectBlur::draw(f32 width, f32 height) { void PostEffectBlur::drawInternal(u8 kernelIdx, u8 p2, f32 f1, f32 f2) { // NONMATCHING nw4r::math::MTX34 mtx; - Kernel &k = field_0x38[kernelIdx]; + Stage &k = field_0x38[kernelIdx]; // Some regswaps and instruction swaps only at the start of the function f32 unk_00 = k.field_0x00; diff --git a/src/egg/gfx/eggPostEffectUnk1.cpp b/src/egg/gfx/eggPostEffectUnk1.cpp index 1b517719..ade510b4 100644 --- a/src/egg/gfx/eggPostEffectUnk1.cpp +++ b/src/egg/gfx/eggPostEffectUnk1.cpp @@ -50,7 +50,7 @@ void PostEffectUnk1::setMaterialInternal() { GXSetNumTevStages(numStages); for (int i = 0; i < numStages; i++) { - Kernel &k = field_0x34[i]; + Stage &k = field_0x34[i]; GXTevStageID stage = static_cast(i); GXSetTevDirect(stage); GXSetTevSwapMode(stage, GX_TEV_SWAP0, GX_TEV_SWAP0); diff --git a/src/egg/gfx/eggPostEffectUnk2.cpp b/src/egg/gfx/eggPostEffectUnk2.cpp index d44f65cc..f61134cf 100644 --- a/src/egg/gfx/eggPostEffectUnk2.cpp +++ b/src/egg/gfx/eggPostEffectUnk2.cpp @@ -1,3 +1,188 @@ #include "egg/gfx/eggPostEffectUnk2.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggGXUtility.h" +#include "egg/math/eggVector.h" +#include "nw4r/math/math_triangular.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/GX/GXVert.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +PostEffectUnk2::PostEffectUnk2() { + // NONMATCHING + field_0x2C = 0; + field_0x30 = 0; + field_0x34 = 1; + field_0x35 = 0xFE; + field_0x36 = 7; + field_0x38 = 0.0f; + field_0x3C = 0.0f; + field_0x40 = 1.0f; + field_0x44 = 1.0f; + field_0x48 = 1.0f; + mpTexture = new CpuTexture(32, 4, GX_TF_RGBA8); + mpTexture->configure(); + mpTexture->allocate(nullptr); + mpTexture->setWrapS(GX_CLAMP); + mpTexture->setWrapT(GX_CLAMP); + for (u16 y = 0; y < mpTexture->getHeight(); y++) { + for (u16 x = 0; x < mpTexture->getWidth(); x++) { + // The conversion constant 0x43000000 needs to + // be stored at the start of the function... + f32 xF = x; + f32 widF = mpTexture->getWidth() - 1; + f32 ratio = nw4r::ut::Min(xF / widF, 1.0f); + u8 val = ratio * 255.0f; + GXColor color = {val, val, val, val}; + mpTexture->setColor(x, y, color); + } + } + + mpTexture->flush(); + field_0x00 = 0; +} + +PostEffectUnk2::~PostEffectUnk2() { + delete mpTexture; +} + +void PostEffectUnk2::draw(f32 width, f32 height) { + // NONMATCHING + setMaterialInternal(); + setVtxState(); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_CLR_RGBA, GX_F32, 0); + GXSetVtxDesc(GX_VA_TEX1, GX_DIRECT); + + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, mScaleX * width, mScaleY * height, 1.0f); + PSMTXTransApply(mtx, mtx, mOffsetX, mOffsetY, 0.0f); + GXLoadPosMtxImm(mtx, 0); + + static const f32 floats1[2][2] = { + {-1.0f, 1.0f}, + { 0.0f, 0.0f}, + }; + static const f32 floats2[2][2] = { + { 0.0f, 0.0f}, + {-1.0f, 1.0f}, + }; + + // TODO + f32 s1 = field_0x40 / mpCapTexture->getWidth(); + f32 s2 = field_0x40 / mpCapTexture->getHeight(); + f32 f = 0.0f; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + EGG::Vector3f(0.0f, 0.0f, 0.0f); + f32 sin, cos; + nw4r::math::SinCosRad(&sin, &cos, f); + nw4r::math::MTX34 mtx2; + mtx2._00 = cos; + mtx2._01 = -sin; + mtx2._02 = -cos * f + sin * f + (s1 * floats1[i][j]); + mtx2._03 = f; + mtx2._10 = sin; + mtx2._11 = cos; + mtx2._12 = -sin * f - cos * f + (s2 * floats2[i][j]); + mtx2._13 = f; + GXLoadTexMtxImm(mtx2, GXUtility::getTexMtxID(j), GX_MTX_2x4); + } + if (i == 1 && field_0x2C <= 1) { + GXSetBlendMode(GX_BM_LOGIC, GX_BL_ZERO, GX_BL_ZERO, GX_LO_OR); + } + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition2u8(0, 0); + GXPosition2f32(field_0x38, field_0x3C); + GXPosition2u8(1, 1); + GXPosition2f32(field_0x38, field_0x3C); + GXPosition2u8(2, 2); + GXPosition2f32(field_0x38, field_0x3C); + GXPosition2u8(3, 3); + GXPosition2f32(field_0x38, field_0x3C); + } +} + +void PostEffectUnk2::setMaterialInternal() { + loadTextureInternal(); + setMatColorChannel(); + GXSetNumTexGens(4); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, 0x3c, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX0, 0x1e, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX0, 0x21, 0, 0x7d); + GXSetNumIndStages(3); + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, mTexMapId); + GXSetIndTexOrder(GX_INDTEXSTAGE1, GX_TEXCOORD2, mTexMapId); + GXSetIndTexOrder(GX_INDTEXSTAGE2, GX_TEXCOORD3, mTexMapId); + setMatPE(); + mpTexture->load(GX_TEXMAP1); + + GXSetNumTevStages(4); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL); + + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + + GXSetTevIndirect( + GX_TEVSTAGE1, GX_INDTEXSTAGE1, GX_ITF_8, GX_ITB_NONE, GX_ITM_1, GX_ITW_0, GX_ITW_0, true, false, GX_ITBA_OFF + ); + + GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + GX_TEVSTAGE2, GX_INDTEXSTAGE2, GX_ITF_8, GX_ITB_NONE, GX_ITM_2, GX_ITW_0, GX_ITW_0, true, false, GX_ITBA_OFF + ); + + GXSetTevSwapMode(GX_TEVSTAGE3, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD_NULL, GX_TEXMAP1, GX_COLOR_NULL); + if (field_0x2C == 2) { + GXSetTevColorIn(GX_TEVSTAGE3, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE3, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_GREATER, field_0x35); + } else { + GXSetTevColorIn(GX_TEVSTAGE3, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevAlphaIn(GX_TEVSTAGE3, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + } + GXSetTevColorOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + GX_TEVSTAGE3, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, true, false, GX_ITBA_OFF + ); + for (int i = 0; i < 3; i++) { + static const f32 sFloats[2][3] = { + { 1.0f, -1.0f, -1.0f}, + {-1.0f, 1.0f, 1.0f}, + }; + + s16 scale = field_0x36; + f32 f1 = (i != 0 ? 0.5f : 1.0f) * (sFloats[field_0x30][i] * 0.5f); + f32 f2 = (i == 0 ? field_0x44 : 0.0f) * 0.5f; + + f32 v[2][3] = { + {f1 / 256.0f, f1, 0.0f}, + {f2 / 256.0f, f2, 0.0f}, + }; + + GXSetIndTexMtx(static_cast(i + 1), v, scale - 2); + } +} + +} // namespace EGG