diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 73a15530..724250f1 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2167,6 +2167,8 @@ egg/prim/eggAssert.cpp: egg/gfx/eggCamera.cpp: .text start:0x8049C5C0 end:0x8049CAC8 + .data start:0x8056ED00 end:0x8056ED60 + .sdata2 start:0x8057F3B8 end:0x8057F3C8 egg/gfx/eggPalette.cpp: .text start:0x8049CAD0 end:0x8049CB44 @@ -2278,9 +2280,13 @@ egg/gfx/eggPostEffectBase.cpp: egg/gfx/eggPostEffectBlur.cpp: .text start:0x804AF4C0 end:0x804AFC04 + .data start:0x8056F170 end:0x8056F190 + .sdata2 start:0x8057F750 end:0x8057F788 egg/gfx/eggPostEffectUnk1.cpp: .text start:0x804AFC10 end:0x804B0098 + .data start:0x8056F190 end:0x8056F1B0 + .sdata2 start:0x8057F788 end:0x8057F798 egg/gfx/eggPostEffectUnk2.cpp: .text start:0x804B00A0 end:0x804B0AA4 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 9edae6db..1ca9a08a 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -677,7 +677,7 @@ fn_8001D0C0 = .text:0x8001D0C0; // type:function size:0x35C fn_8001D420 = .text:0x8001D420; // type:function size:0x58 fn_8001D480 = .text:0x8001D480; // type:function size:0x58 fn_8001D4E0 = .text:0x8001D4E0; // type:function size:0x6C -fn_8001D550 = .text:0x8001D550; // type:function size:0x40 +__dt__Q23EGG14PostEffectBlurFv = .text:0x8001D550; // type:function size:0x40 __dt__Q23EGG14PostEffectBaseFv = .text:0x8001D590; // type:function size:0x40 fn_8001D5D0 = .text:0x8001D5D0; // type:function size:0x30 fn_8001D600 = .text:0x8001D600; // type:function size:0x38 @@ -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__Q23EGG10BaseCameraFPQ23EGG10BaseCamera = .text:0x8049C5D0; // type:function size:0x50 +draw__Q23EGG10BaseCameraFv = .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__Q23EGG12LookAtCameraFv = .text:0x8049CAA0; // type:function size:0x1C +getPosition__Q23EGG12LookAtCameraCFv = .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 @@ -26449,7 +26449,7 @@ alloc__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049E900; // type:function size allocWithHeaderDebug__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049E990; // type:function size:0xA8 allocate__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049EA40; // type:function size:0x4 setColor__Q23EGG10CpuTextureFUsUs8_GXColor = .text:0x8049EA50; // type:function size:0x10C -getColor__Q23EGG10CpuTextureFUsUs = .text:0x8049EB60; // type:function size:0x134 +getColor__Q23EGG10CpuTextureCFUsUs = .text:0x8049EB60; // type:function size:0x134 DrawQuadNormal__23@unnamed@eggDrawGX_cpp@FUcUcUcUcUc = .text:0x8049ECA0; // type:function size:0x28 DrawQuadLineStripNormal__23@unnamed@eggDrawGX_cpp@FUcUcUcUcUc = .text:0x8049ECD0; // type:function size:0x7C DrawCircleYPolygonFan__23@unnamed@eggDrawGX_cpp@FRCQ34nw4r4math5MTX34fUs = .text:0x8049ED50; // type:function size:0x318 @@ -26486,7 +26486,7 @@ scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x804A0E60; // type:function size:0 @20@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E90; // type:function size:0x8 FUN_804a0ea0 = .text:0x804A0EA0; // type:function size:0x188 __dt__Q23EGG14PostEffectMaskFv = .text:0x804A1030; // type:function size:0x40 -FUN_804a1070 = .text:0x804A1070; // type:function size:0x40 +__dt__Q23EGG14PostEffectUnk1Fv = .text:0x804A1070; // type:function size:0x40 FUN_804a10b0 = .text:0x804A10B0; // type:function size:0x40 FUN_804a10f0 = .text:0x804A10F0; // type:function size:0x60 FUN_804a1150 = .text:0x804A1150; // type:function size:0x21C @@ -26669,7 +26669,7 @@ createTextureFromBin__Q23EGG19LightTextureManagerFPCv = .text:0x804AD7A0; // typ createTexturesFromBin__Q23EGG19LightTextureManagerFPCv = .text:0x804AD800; // type:function size:0x6C deleteTexture__Q23EGG19LightTextureManagerFi = .text:0x804AD870; // type:function size:0x84 replaceModelTextures__Q23EGG19LightTextureManagerCFQ34nw4r3g3d6ResMdl = .text:0x804AD900; // type:function size:0x84 -replaceModelTexture__Q23EGG19LightTextureManagerCFiQ34nw4r3g3d6ResMdl = .text:0x804AD990; // type:function size:0x104 +replaceModelTexture__Q23EGG19LightTextureManagerCFUsQ34nw4r3g3d6ResMdl = .text:0x804AD990; // type:function size:0x104 getTextureIndex__Q23EGG19LightTextureManagerCFPCc = .text:0x804ADAA0; // type:function size:0x7C setBinaryToTexture__Q23EGG19LightTextureManagerFPCv = .text:0x804ADB20; // type:function size:0x90 correctLightObject__Q23EGG19LightTextureManagerFv = .text:0x804ADBB0; // type:function size:0x90 @@ -26698,15 +26698,15 @@ setMatColorChannel__Q23EGG14PostEffectBaseFv = .text:0x804AEE70; // type:functio setMatInd__Q23EGG14PostEffectBaseFv = .text:0x804AEEE0; // type:function size:0x8 setMatPE__Q23EGG14PostEffectBaseFv = .text:0x804AEEF0; // type:function size:0x7C setBlendModeInternal__Q23EGG14PostEffectBaseFv = .text:0x804AEF70; // type:function size:0xC4 -fn_804AF040__Q23EGG14PostEffectBaseFR8_GXColorRC8_GXColorbf = .text:0x804AF040; // type:function size:0x164 -fn_804AF1B0__Q23EGG14PostEffectBaseFR8_GXColorRC8_GXColorRC8_GXColorf = .text:0x804AF1B0; // type:function size:0x120 +scaleColor__Q23EGG14PostEffectBaseFR8_GXColorRC8_GXColorbf = .text:0x804AF040; // type:function size:0x164 +lerpColor__Q23EGG14PostEffectBaseFR8_GXColorRC8_GXColorRC8_GXColorf = .text:0x804AF1B0; // type:function size:0x120 getBaseTexMtx__Q23EGG14PostEffectBaseCFPQ34nw4r4math5MTX34 = .text:0x804AF2D0; // type:function size:0xE4 setProjection__Q23EGG14PostEffectBaseFRCQ23EGG6Screen = .text:0x804AF3C0; // type:function size:0xF4 -FUN_804af4c0 = .text:0x804AF4C0; // type:function size:0xE0 -FUN_804af5a0 = .text:0x804AF5A0; // type:function size:0x190 -FUN_804af730 = .text:0x804AF730; // type:function size:0x4D4 -FUN_804afc10 = .text:0x804AFC10; // type:function size:0xC0 -FUN_804afcd0 = .text:0x804AFCD0; // type:function size:0x3C8 +__ct__Q23EGG14PostEffectBlurFv = .text:0x804AF4C0; // type:function size:0xE0 +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 @@ -37356,7 +37356,7 @@ __vt__Q23EGG11OrthoCamera = .data:0x8056ED00; // type:object size:0x30 __vt__Q23EGG12LookAtCamera = .data:0x8056ED30; // type:object size:0x30 lbl_8056ED60 = .data:0x8056ED60; // type:object size:0x10 __vt__Q23EGG10CapTexture = .data:0x8056ED70; // type:object size:0x10 -__vt__Q23EGG10CpuTexture = .data:0x8056ED80; // type:object size:0x20 +__vt__Q23EGG10CpuTexture = .data:0x8056ED80; // type:object size:0x10 DummyTexureData = .data:0x8056EDA0; // type:object size:0x40 jumptable_8056EDE0 = .data:0x8056EDE0; // type:object size:0x38 scope:local jumptable_8056EE18 = .data:0x8056EE18; // type:object size:0x48 scope:local @@ -37376,8 +37376,8 @@ __vt__Q23EGG19LightTextureManager = .data:0x8056F0F0; // type:object size:0x1C lbl_8056F110 = .data:0x8056F110; // type:object size:0x9 data:string jumptable_8056F120 = .data:0x8056F120; // type:object size:0x30 scope:local __vt__Q23EGG14PostEffectBase = .data:0x8056F150; // type:object size:0x1C -lbl_8056F170 = .data:0x8056F170; // type:object size:0x20 -lbl_8056F190 = .data:0x8056F190; // type:object size:0x20 +__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__Q23EGG14PostEffectMask = .data:0x8056F1D0; // type:object size:0x1C lbl_8056F1F0 = .data:0x8056F1F0; // type:object size:0x20 diff --git a/include/egg/gfx/eggCpuTexture.h b/include/egg/gfx/eggCpuTexture.h index 2fac0978..7269471f 100644 --- a/include/egg/gfx/eggCpuTexture.h +++ b/include/egg/gfx/eggCpuTexture.h @@ -67,7 +67,8 @@ public: UNKTYPE func_80086C8C(UNKTYPE); void allocTexBuffer(); void allocTexBufferAndHeader(); - void setColor(u16, u16, GXColor); + void setColor(u16 x, u16 y, GXColor color); + GXColor getColor(u16 x, u16 y) const; bool checkIsConfigure() const { return mFlags & CONFIGURED; diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index ec3445b5..16a036f1 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -31,8 +31,8 @@ protected: void setMatInd(); void setMatPE(); void setBlendModeInternal(); - static void fn_804AF040(GXColor &, const GXColor &, bool, f32); - static void fn_804AF1B0(GXColor &, const GXColor &, const GXColor &, f32); + static void scaleColor(GXColor &, const GXColor &, bool, f32); + static void lerpColor(GXColor &, const GXColor &, const GXColor &, f32); void getBaseTexMtx(nw4r::math::MTX34 *mtx) const; static void setProjection(const EGG::Screen &screen); diff --git a/include/egg/gfx/eggPostEffectBlur.h b/include/egg/gfx/eggPostEffectBlur.h index 4c116d62..02459743 100644 --- a/include/egg/gfx/eggPostEffectBlur.h +++ b/include/egg/gfx/eggPostEffectBlur.h @@ -2,21 +2,43 @@ #define EGG_POST_EFFECT_BLUR_H #include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggPostEffectBase.h" + namespace EGG { -class PostEffectBlur { +class PostEffectBlur : PostEffectBase { + struct Kernel { + /* 0x00 */ u8 field_0x00; + /* 0x01 */ GXColor field_0x01; + /* 0x08 */ f32 field_0x08; + /* 0x0C */ f32 field_0x0C; + + void init(GXColor clr) { + field_0x00 = 16; + field_0x01 = clr; + field_0x08 = 1.0f; + field_0x0C = 0.0f; + } + }; + public: PostEffectBlur(); - ~PostEffectBlur() {} + virtual ~PostEffectBlur() {} + + virtual void draw(f32 width, f32 height) override; // at 0xC void setField0x30(f32 val) { field_0x30 = val; } private: - u8 _0x00[0x30 - 0x00]; - f32 field_0x30; - u8 _0x03[0x78 - 0x34]; + void drawInternal(u8, u8, f32, f32); + + /* 0x2C */ u8 field_0x2C; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ f32 field_0x34; + /* 0x38 */ Kernel field_0x38[4]; }; } // namespace EGG diff --git a/include/egg/gfx/eggPostEffectUnk1.h b/include/egg/gfx/eggPostEffectUnk1.h index 24b1df6e..2d93e9be 100644 --- a/include/egg/gfx/eggPostEffectUnk1.h +++ b/include/egg/gfx/eggPostEffectUnk1.h @@ -1,6 +1,31 @@ #ifndef EGG_POST_EFFECT_UNK1_H #define EGG_POST_EFFECT_UNK1_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "rvl/GX/GXTypes.h" +namespace EGG { + +class PostEffectUnk1 : public PostEffectBase { + // Size 0x18 + struct Kernel { + /* 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]; +}; + +} // namespace EGG #endif diff --git a/src/egg/gfx/eggCamera.cpp b/src/egg/gfx/eggCamera.cpp index 3e785cbf..77679d91 100644 --- a/src/egg/gfx/eggCamera.cpp +++ b/src/egg/gfx/eggCamera.cpp @@ -26,6 +26,7 @@ Matrix34f &LookAtCamera::getViewMatrixOld() { } void LookAtCamera::doUpdateMatrix() { + // NONMATCHING mOtherMtx.copyFrom(mViewMtx); EGG::Vector3f posRight = mPosition; posRight -= mRight; @@ -61,6 +62,7 @@ OrthoCamera::OrthoCamera() { } void OrthoCamera::update_parms() { + // NONMATCHING f32 z = field_0x8C; f32 sin = Math::sin(field_0x88); f32 cos = Math::cos(field_0x88); diff --git a/src/egg/gfx/eggCpuTexture.cpp b/src/egg/gfx/eggCpuTexture.cpp index e6b3322a..9052ff8b 100644 --- a/src/egg/gfx/eggCpuTexture.cpp +++ b/src/egg/gfx/eggCpuTexture.cpp @@ -132,4 +132,80 @@ void CpuTexture::allocate(Heap *pHeap) { alloc(pHeap); } +void CpuTexture::setColor(u16 x, u16 y, GXColor color) { + // NONMATCHING + switch (getFormat()) { + case GX_TF_RGBA8: + case GX_TF_Z24X8: { + int offset = ((x >> 2) + (y >> 2) * (getWidth() / 4)) * 0x40 + (y & 3) * 8 + (x & 3) * 2; + u8 *dat = static_cast(getBuffer()) + offset; + dat[0] = color.a; + dat[1] = color.r; + dat[0x20] = color.g; + dat[0x21] = color.b; + break; + } + case GX_TF_I8: + case GX_TF_Z8: { + // TODO + int offset = ((x >> 3) + (y >> 2) * (getWidth() / 8)) * 0x20 + (x & 3) * 8 + (x & 7); + u8 *dat = static_cast(getBuffer()) + offset; + dat[0] = color.r; + break; + } + + case GX_TF_IA8: + case GX_TF_Z16: { + int offset = ((x >> 2) + (y >> 2) * (getWidth() / 4)) * 0x20 + (y & 3) * 8 + (x & 3) * 2; + u8 *dat = static_cast(getBuffer()) + offset; + dat[0] = color.a; + dat[1] = color.r; + break; + } + default: break; + } +} + +GXColor CpuTexture::getColor(u16 x, u16 y) const { + // NONMATCHING + GXColor c; + switch (getFormat()) { + case GX_TF_RGBA8: + case GX_TF_Z24X8: { + int offset = ((x >> 2) + (y >> 2) * (getWidth() / 4)) * 0x40 + (y & 3) * 8 + (x & 3) * 2; + u8 *dat = static_cast(getBuffer()) + offset; + c.r = dat[1]; + c.g = dat[0x20]; + c.b = dat[0x21]; + c.a = dat[0]; + break; + } + case GX_TF_I8: + case GX_TF_Z8: { + // TODO + int offset = ((x >> 3) + (y >> 2) * (getWidth() / 8)) * 0x20 + (x & 3) * 8 + (x & 7); + u8 *dat = static_cast(getBuffer()) + offset; + c.a = dat[0]; + c.b = dat[0]; + c.g = dat[0]; + c.r = dat[0]; + break; + } + + case GX_TF_IA8: + case GX_TF_Z16: { + int offset = ((x >> 2) + (y >> 2) * (getWidth() / 4)) * 0x20 + (y & 3) * 8 + (x & 3) * 2; + u8 *dat = static_cast(getBuffer()) + offset; + // TODO + c.a = dat[0]; + c.b = dat[1]; + c.g = dat[1]; + c.r = dat[1]; + break; + } + default: break; + } + return c; +} + } // namespace EGG diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp index 101caa72..2c93e001 100644 --- a/src/egg/gfx/eggPostEffectBase.cpp +++ b/src/egg/gfx/eggPostEffectBase.cpp @@ -96,7 +96,7 @@ void PostEffectBase::setBlendModeInternal() { } } -void PostEffectBase::fn_804AF040(GXColor &out, const GXColor &c, bool bClamp, f32 amount) { +void PostEffectBase::scaleColor(GXColor &out, const GXColor &c, bool bClamp, f32 amount) { f32 fs[4]; fs[0] = c.r * amount; fs[1] = c.g * amount; @@ -116,7 +116,7 @@ void PostEffectBase::fn_804AF040(GXColor &out, const GXColor &c, bool bClamp, f3 } } -void PostEffectBase::fn_804AF1B0(GXColor &out, const GXColor &c1, const GXColor &c2, f32 amount) { +void PostEffectBase::lerpColor(GXColor &out, const GXColor &c1, const GXColor &c2, f32 amount) { out.r = c1.r + amount * (c2.r - c1.r); out.g = c1.g + amount * (c2.g - c1.g); out.b = c1.b + amount * (c2.b - c1.b); diff --git a/src/egg/gfx/eggPostEffectBlur.cpp b/src/egg/gfx/eggPostEffectBlur.cpp index d988b7bb..3fd180f9 100644 --- a/src/egg/gfx/eggPostEffectBlur.cpp +++ b/src/egg/gfx/eggPostEffectBlur.cpp @@ -1,3 +1,131 @@ #include "egg/gfx/eggPostEffectBlur.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggGXUtility.h" +#include "math.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/GXTev.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +PostEffectBlur::PostEffectBlur() { + // NONMATCHING + static const GXColor c = {0xD7, 0xD7, 0xD7, 0xD7}; + field_0x2C = 1; + field_0x30 = 1.0f; + field_0x34 = 1.0f; + for (int i = 0; i < ARRAY_LENGTH(field_0x38); i++) { + field_0x38[i].init(c); + } +} + +void PostEffectBlur::draw(f32 width, f32 height) { + // NONMATCHING + loadTextureInternal(); + setMatColorChannel(); + setMatInd(); + setMatPE(); + setVtxState(); + f32 f1 = 1.0f / mpCapTexture->getWidth(); + f32 f2 = 1.0f / mpCapTexture->getHeight(); + for (u8 i = 0; i < field_0x2C; i++) { + // Regswap + int maxNum = field_0x38[i].field_0x00 - 1; + for (u8 b = 0; b <= maxNum / 8; b++) { + drawInternal(i, b, f1, f2); + drawScreenInternal(mOffsetX, mOffsetY, width * mScaleX, height * mScaleY); + DrawGX::SetBlendMode(DrawGX::BLEND_2); + } + } +} + +void PostEffectBlur::drawInternal(u8 kernelIdx, u8 p2, f32 f1, f32 f2) { + // NONMATCHING + nw4r::math::MTX34 mtx; + Kernel &k = field_0x38[kernelIdx]; + + // Some regswaps and instruction swaps only at the start of the function + f32 unk_00 = k.field_0x00; + int unk_00_scale = (p2 & 0x1F) * 8; + + f32 rad1 = (k.field_0x08 - M_PI * mRotation); + f32 abc = (2.0f * M_PI / unk_00); + + f32 f3 = k.field_0x0C * f1; + f32 f4 = k.field_0x0C * f2; + + u8 numTexGens = k.field_0x00 - unk_00_scale; + if (numTexGens > 8) { + numTexGens = 8; + } + + getBaseTexMtx(&mtx); + GXSetNumTexGens(numTexGens); + for (int id = 0; id < numTexGens; id++) { + int texMtxId = GXUtility::getTexMtxID(id); + GXSetTexCoordGen2(static_cast(id), GX_TG_MTX2x4, GX_TG_TEX0, texMtxId, false, 0x7D); + f32 sin, cos; + nw4r::math::SinCosRad(&sin, &cos, rad1 + abc * unk_00_scale); + nw4r::math::MTX34 m( + // clang-format off + 1.0f, 0.0f, cos * f3, 0.0f, + 0.0f, 1.0f, sin * f4, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + // clang-format on + ); + // OK from here + PSMTXConcat(m, mtx, m); + GXLoadTexMtxImm(m, texMtxId, GX_MTX_2x4); + unk_00_scale++; + } + + bool isSmallColor = k.field_0x01.r < 0x80 && k.field_0x01.g < 0x80 && k.field_0x01.b < 0x80; + bool isSmallAlpha = k.field_0x01.a < 0x80; + f32 colorScale = (isSmallColor ? 2.0f : 1.0f) * field_0x30; + f32 alphaScale = (isSmallAlpha ? 2.0f : 1.0f) * field_0x30; + + f32 clrs[] = { + k.field_0x01.r * colorScale, + k.field_0x01.g * colorScale, + k.field_0x01.b * colorScale, + k.field_0x01.a * alphaScale, + }; + GXColor clr; + clr.r = clrs[0] < 255.0f ? clrs[0] : 255.0f; + clr.g = clrs[1] < 255.0f ? clrs[1] : 255.0f; + clr.b = clrs[2] < 255.0f ? clrs[2] : 255.0f; + clr.a = clrs[3] < 255.0f ? clrs[3] : 255.0f; + + GXSetTevKColor(GX_KCOLOR0, clr); + GXSetNumTevStages(numTexGens); + for (int id = 0; id < numTexGens; id++) { + GXTevStageID stage = static_cast(id); + GXSetTevDirect(stage); + GXSetTevSwapMode(stage, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXTevColorArg a1 = id > 0 ? GX_CC_CPREV : GX_CC_ZERO; + GXTevAlphaArg a2 = id > 0 ? GX_CA_APREV : GX_CA_ZERO; + + GXSetTevKColorSel(stage, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(stage, GX_TEV_KASEL_K0_A); + GXSetTevOrder(stage, static_cast(id), mTexMapId, GX_COLOR_NULL); + GXSetTevColorIn(stage, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, a1); + GXSetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, a2); + + bool isLast = stage == numTexGens - 1; + bool colorArg = isLast; + + GXTevScale colorScale = isSmallColor && isLast ? GX_CS_DIVIDE_2 : GX_CS_SCALE_1; + GXTevScale alphaScale = isSmallAlpha && colorArg ? GX_CS_DIVIDE_2 : GX_CS_SCALE_1; + GXSetTevColorOp(stage, GX_TEV_ADD, GX_TB_ZERO, colorScale, colorArg, GX_TEVPREV); + GXSetTevAlphaOp(stage, GX_TEV_ADD, GX_TB_ZERO, alphaScale, isLast, GX_TEVPREV); + } +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectMask.cpp b/src/egg/gfx/eggPostEffectMask.cpp index 17d6e895..5162e3a7 100644 --- a/src/egg/gfx/eggPostEffectMask.cpp +++ b/src/egg/gfx/eggPostEffectMask.cpp @@ -15,7 +15,7 @@ void PostEffectMask::setMaterialInternal() { bool hasTex2 = mpCapTexture2 != nullptr; loadTextureInternal(); GXColor resColor; - fn_804AF040(resColor, mColor, false, field_0x34); + scaleColor(resColor, mColor, false, field_0x34); setMatColorChannel(); GXSetNumTexGens(2); diff --git a/src/egg/gfx/eggPostEffectUnk1.cpp b/src/egg/gfx/eggPostEffectUnk1.cpp index f85768e6..1b517719 100644 --- a/src/egg/gfx/eggPostEffectUnk1.cpp +++ b/src/egg/gfx/eggPostEffectUnk1.cpp @@ -1,3 +1,94 @@ #include "egg/gfx/eggPostEffectUnk1.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggGXUtility.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXAttr.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +PostEffectUnk1::PostEffectUnk1() { + // NONMATCHING + field_0x2C = 1; + field_0x2D = 1; + field_0x30 = 0.5f; + for (int i = 0; i < ARRAY_LENGTH(field_0x34); i++) { + field_0x34[i].field_0x00 = nullptr; + field_0x34[i].field_0x08 = DrawGX::WHITE; + field_0x34[i].field_0x0C = 1.0f; + field_0x34[i].field_0x10 = 0; + } +} + +void PostEffectUnk1::setMaterialInternal() { + u8 hasExtraStage = (mpCapTexture != nullptr && (field_0x2D & 1) == 0) ? 1 : 0; + u8 numStages = field_0x2C + hasExtraStage * 2; + setMatColorChannel(); + nw4r::math::MTX34 mtx; + getBaseTexMtx(&mtx); + u8 numStagesFirst = field_0x2C + hasExtraStage; + GXSetNumTexGens(numStagesFirst); + for (int i = 0; i < numStagesFirst; i++) { + int texMtxIdx = GXUtility::getTexMtxID(i); + GXSetTexCoordGen2(static_cast(i), GX_TG_MTX2x4, GX_TG_TEX0, texMtxIdx, 0, 0x7D); + if (i < field_0x2C) { + field_0x34[i].field_0x00->load(field_0x34[i].mTexMapId); + } else { + loadTextureInternal(); + } + GXLoadTexMtxImm(mtx, texMtxIdx, GX_MTX_2x4); + } + + f32 v = field_0x30 * 255.0f; + GXColor c = {v, v, v, v}; + setMatInd(); + GXSetNumTevStages(numStages); + + for (int i = 0; i < numStages; i++) { + Kernel &k = field_0x34[i]; + GXTevStageID stage = static_cast(i); + GXSetTevDirect(stage); + GXSetTevSwapMode(stage, GX_TEV_SWAP0, GX_TEV_SWAP0); + if (i < field_0x2C) { + GXColor scaledColor; + scaleColor(scaledColor, k.field_0x08, false, k.field_0x0C); + + GXSetTevKColorSel(stage, static_cast(GX_TEV_KCSEL_K0 + i)); + GXSetTevKAlphaSel(stage, static_cast(GX_TEV_KASEL_K0_A + i)); + + GXSetTevKColor(static_cast(i), scaledColor); + GXSetTevOrder(stage, static_cast(i), k.mTexMapId, GX_COLOR_NULL); + GXSetTevColorIn(stage, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, stage == 0 ? GX_CC_ZERO : GX_CC_CPREV); + GXSetTevColorOp( + stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, i == field_0x2C - 1 ? GX_TEVREG0 : GX_TEVPREV + ); + GXSetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, stage == 0 ? GX_CA_ZERO : GX_CA_APREV); + GXSetTevAlphaOp( + stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, i == field_0x2C - 1 ? GX_TEVREG0 : GX_TEVPREV + ); + } else if (stage == field_0x2C) { + GXSetTevKColorSel(stage, GX_TEV_KCSEL_K2); + GXSetTevKAlphaSel(stage, GX_TEV_KASEL_K2_A); + GXSetTevKColor(GX_KCOLOR2, c); + GXSetTevOrder(stage, static_cast(i), mTexMapId, GX_COLOR_NULL); + GXSetTevColorIn(stage, GX_CC_KONST, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(stage, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_4, 1, GX_TEVPREV); + GXSetTevAlphaIn(stage, GX_CA_KONST, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(stage, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_4, true, GX_TEVPREV); + } else { + GXSetTevOrder(stage, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevColorIn(stage, GX_CC_C0, GX_CC_ZERO, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(stage, GX_CA_A0, GX_CA_ZERO, GX_CA_APREV, GX_CA_ZERO); + GXSetTevAlphaOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + } + } + setMatPE(); +} + +} // namespace EGG