From 9b7889f03497dfae5792ee24803a80a7cb6a7281 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 15 Mar 2025 17:33:48 +0100 Subject: [PATCH 01/62] Some small classes --- config/SOUE01/splits.txt | 21 ++++- config/SOUE01/symbols.txt | 28 +++--- configure.py | 10 ++- include/egg/gfx/eggFog.h | 40 ++++++--- include/egg/gfx/eggFogManager.h | 44 ++++++++++ include/egg/gfx/eggG3DUtility.h | 16 +++- include/egg/gfx/eggGlobalDrawState.h | 22 ++++- include/egg/gfx/eggIScnProc.h | 41 ++++++++- include/egg/gfx/eggLight.h | 10 ++- include/egg/gfx/eggScreenEffectBase.h | 19 +++- include/egg/gfx/eggStateEfb.h | 9 +- include/egg/gfx/eggStateGX.h | 8 ++ include/egg/prim/eggBinary.h | 81 +++++++++++++++-- include/m/m3d/m3d.h | 2 +- include/nw4r/g3d/g3d_fog.h | 7 ++ src/egg/gfx/eggFog.cpp | 67 +++++++++++++- src/egg/gfx/eggFogManager.cpp | 69 +++++++++++++++ src/egg/gfx/eggGlobalDrawState.cpp | 36 +++++++- src/egg/gfx/eggIScnProc.cpp | 87 ++++++++++++++++++- .../gfx/{eggLight.cpp => eggLightManager.cpp} | 0 src/egg/gfx/eggLightObject.cpp | 3 + src/egg/gfx/eggScreenEffectBase.cpp | 8 +- src/m/m3d/m3d.cpp | 2 +- 23 files changed, 576 insertions(+), 54 deletions(-) create mode 100644 include/egg/gfx/eggFogManager.h create mode 100644 src/egg/gfx/eggFogManager.cpp rename src/egg/gfx/{eggLight.cpp => eggLightManager.cpp} (100%) create mode 100644 src/egg/gfx/eggLightObject.cpp diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index b6711ae5..28407b19 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2200,7 +2200,14 @@ egg/gfx/eggDrawPathUnk2.cpp: .text start:0x804A4BF0 end:0x804A54E8 egg/gfx/eggFog.cpp: - .text start:0x804A54F0 end:0x804A5F60 + .text start:0x804A54F0 end:0x804A5A08 + .data start:0x8056EFF0 end:0x8056F010 + .sdata start:0x80574F20 end:0x80574F28 + .sdata2 start:0x8057F608 end:0x8057F618 + +egg/gfx/eggFogManager.cpp: + .text start:0x804A5A10 end:0x804A5F60 + .data start:0x8056F010 end:0x8056F030 egg/gfx/eggFrustum.cpp: .text start:0x804A5F60 end:0x804A6854 @@ -2215,15 +2222,21 @@ egg/gfx/eggGfxEngine.cpp: egg/gfx/eggGlobalDrawState.cpp: .text start:0x804A7750 end:0x804A7814 .ctors start:0x804DB9A0 end:0x804DB9A4 + .sbss start:0x80576838 end:0x80576848 + .bss start:0x80674E48 end:0x80674E78 egg/gfx/eggGXUtility.cpp: .text start:0x804A7820 end:0x804A7BC0 egg/gfx/eggIScnProc.cpp: .text start:0x804A7BC0 end:0x804A7F7C + .data start:0x8056F058 end:0x8056F068 -egg/gfx/eggLight.cpp: - .text start:0x804A7F80 end:0x804AB24C +egg/gfx/eggLightManager.cpp: + .text start:0x804A7F80 end:0x804A9808 + +egg/gfx/eggLightObject.cpp: + .text start:0x804A9810 end:0x804AB24C egg/gfx/eggLightTexture.cpp: .text start:0x804AB250 end:0x804AD448 @@ -2263,6 +2276,8 @@ egg/gfx/eggScreen.cpp: egg/gfx/eggScreenEffectBase.cpp: .text start:0x804B30C0 end:0x804B30EC .ctors start:0x804DB9AC end:0x804DB9B0 + .data start:0x8056F268 end:0x8056F278 + .bss start:0x80674F88 end:0x80675010 egg/gfx/eggScreenEffectBlur.cpp: .text start:0x804B30F0 end:0x804B3D98 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 9fb3a09b..9b81b258 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -9781,7 +9781,7 @@ fn_80171BD0 = .text:0x80171BD0; // type:function size:0xA90 fn_80172660 = .text:0x80172660; // type:function size:0x4C fn_801726B0 = .text:0x801726B0; // type:function size:0x218 EGG__DrawPathBase____dt = .text:0x801728D0; // type:function size:0x5C -fn_80172930 = .text:0x80172930; // type:function size:0x40 +__dt__Q23EGG16ScreenEffectBaseFv = .text:0x80172930; // type:function size:0x40 fn_80172970 = .text:0x80172970; // type:function size:0xB4 fn_80172A30 = .text:0x80172A30; // type:function size:0x40 fn_80172A70 = .text:0x80172A70; // type:function size:0x10DC @@ -10673,7 +10673,7 @@ nextPhase__22sFPhase<11dStageMgr_c>Fv = .text:0x8019C420; // type:function size: hasReachedEnd__22sFPhase<11dStageMgr_c>CFv = .text:0x8019C430; // type:function size:0x2C fn_8019C460 = .text:0x8019C460; // type:function size:0x10 fn_8019C470 = .text:0x8019C470; // type:function size:0x10 -fn_8019C480 = .text:0x8019C480; // type:function size:0x10 +SetBinary__Q23EGG19IBinaryFPCv = .text:0x8019C480; // type:function size:0x10 fn_8019C490 = .text:0x8019C490; // type:function size:0x8 fn_8019C4A0 = .text:0x8019C4A0; // type:function size:0x10 fn_8019C4B0 = .text:0x8019C4B0; // type:function size:0x8 @@ -26585,7 +26585,7 @@ createScnProc__Q23EGG8IScnProcFUsP12MEMAllocator = .text:0x804A7C80; // type:fun setPriorityScnProc__Q23EGG8IScnProcFUsUcb = .text:0x804A7D90; // type:function size:0xBC pushBackToScnGroup__Q23EGG8IScnProcFPQ34nw4r3g3d8ScnGroup = .text:0x804A7E50; // type:function size:0x84 drawProcFunc__Q23EGG8IScnProcFPQ34nw4r3g3d7ScnProcb = .text:0x804A7EE0; // type:function size:0x78 -EGG__IScnProc__drawProcFuncNoGlobalState = .text:0x804A7F60; // type:function size:0x1C +drawProcFuncNoGlobalState__Q23EGG8IScnProcFPQ34nw4r3g3d7ScnProcb = .text:0x804A7F60; // type:function size:0x1C __ct__Q23EGG12LightManagerFUlUlUc = .text:0x804A7F80; // type:function size:0x1A8 __ct__Q33EGG12LightManager9LightDataFv = .text:0x804A8130; // type:function size:0x30 __dt__Q23EGG11LightObjectFv = .text:0x804A8160; // type:function size:0x40 @@ -37364,11 +37364,11 @@ lbl_8056EE60 = .data:0x8056EE60; // type:object size:0x50 lbl_8056EEB0 = .data:0x8056EEB0; // type:object size:0x78 lbl_8056EF28 = .data:0x8056EF28; // type:object size:0x78 lbl_8056EFA0 = .data:0x8056EFA0; // type:object size:0x50 -EGG__Fog__vtable = .data:0x8056EFF0; // type:object size:0x20 -EGG__FogManager__vtable = .data:0x8056F010; // type:object size:0x20 +__vt__Q23EGG3Fog = .data:0x8056EFF0; // type:object size:0x20 +__vt__Q23EGG10FogManager = .data:0x8056F010; // type:object size:0x20 EGG__Frustum__vtable = .data:0x8056F030; // type:object size:0x18 EGG__GfxEnginer__Configuration__vtable = .data:0x8056F048; // type:object size:0x10 -lbl_8056F058 = .data:0x8056F058; // type:object size:0x10 +__vt__Q23EGG8IScnProc = .data:0x8056F058; // type:object size:0x10 EGG__LightManager__vtable = .data:0x8056F068; // type:object size:0x30 EGG__LightObject__vtable = .data:0x8056F098; // type:object size:0x20 EGG__LightTexture__vtable = .data:0x8056F0B8; // type:object size:0x38 @@ -37384,7 +37384,7 @@ lbl_8056F1F0 = .data:0x8056F1F0; // type:object size:0x20 lbl_8056F210 = .data:0x8056F210; // type:object size:0x20 sTVModeInfo__Q23EGG6Screen = .data:0x8056F230; // type:object size:0x24 data:2byte EGG__Screen__vtable = .data:0x8056F254; // type:object size:0x14 -lbl_8056F268 = .data:0x8056F268; // type:object size:0x10 +__vt__Q23EGG16ScreenEffectBase = .data:0x8056F268; // type:object size:0xC lbl_8056F278 = .data:0x8056F278; // type:object size:0x38 lbl_8056F2B0 = .data:0x8056F2B0; // type:object size:0x10 __vt__Q23EGG9ArcPlayer = .data:0x8056F2C0; // type:object size:0x5C @@ -41152,13 +41152,13 @@ EGG__DrawGX__sTexMapDefault = .sbss:0x8057680C; // type:object size:0x4 data:4by 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 -lbl_80576824 = .sbss:0x80576824; // type:object size:0x4 data:4byte +sAllocator__Q23EGG10G3DUtility = .sbss:0x80576824; // type:object size:0x4 data:4byte lbl_80576828 = .sbss:0x80576828; // type:object size:0x4 data:4byte lbl_8057682C = .sbss:0x8057682C; // type:object size:0x4 data:4byte lbl_80576830 = .sbss:0x80576830; // type:object size:0x8 data:4byte -EGG__GlobalDrawState__spScreen = .sbss:0x80576838; // type:object size:0x4 data:4byte -EGG__GlobalDrawState__sCameraID = .sbss:0x8057683C; // type:object size:0x2 data:2byte -lbl_80576840 = .sbss:0x80576840; // type:object size:0x8 data:4byte +spScreen__Q23EGG15GlobalDrawState = .sbss:0x80576838; // type:object size:0x4 data:4byte +sCameraId__Q23EGG15GlobalDrawState = .sbss:0x8057683C; // type:object size:0x2 data:2byte +sDrawFlag__Q23EGG15GlobalDrawState = .sbss:0x80576840; // type:object size:0x4 data:4byte lbl_80576848 = .sbss:0x80576848; // type:object size:0x2 data:2byte lbl_8057684A = .sbss:0x8057684A; // type:object size:0x2 data:2byte lbl_8057684C = .sbss:0x8057684C; // type:object size:0x2 data:2byte @@ -41186,7 +41186,7 @@ lbl_805768A4 = .sbss:0x805768A4; // type:object size:0x4 data:4byte lbl_805768A8 = .sbss:0x805768A8; // type:object size:0x4 data:4byte lbl_805768AC = .sbss:0x805768AC; // type:object size:0x1 data:byte lbl_805768B0 = .sbss:0x805768B0; // type:object size:0x2 data:2byte -lbl_805768B2 = .sbss:0x805768B2; // type:object size:0x6 data:2byte +s_commandFlag__Q23EGG7StateGX = .sbss:0x805768B2; // type:object size:0x6 data:2byte lbl_805768B8 = .sbss:0x805768B8; // type:object size:0x4 data:4byte lbl_805768BC = .sbss:0x805768BC; // type:object size:0x4 data:4byte lbl_805768C0 = .sbss:0x805768C0; // type:object size:0x4 data:4byte @@ -49802,12 +49802,12 @@ buf__Q23EGG6Assert = .bss:0x80674C60; // type:object size:0x104 lbl_80674D68 = .bss:0x80674D68; // type:object size:0x90 sCameraMtx = .bss:0x80674DF8; // type:object size:0x30 data:float lbl_80674E28 = .bss:0x80674E28; // type:object size:0x20 -lbl_80674E48 = .bss:0x80674E48; // type:object size:0x30 +sMtx__Q23EGG15GlobalDrawState = .bss:0x80674E48; // type:object size:0x30 CPU_TEX_ARR = .bss:0x80674E78; // type:object size:0x48 data:4byte lbl_80674EC0 = .bss:0x80674EC0; // type:object size:0x30 data:float lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0x10 data:float lbl_80674F00 = .bss:0x80674F00; // type:object size:0x88 data:4byte -lbl_80674F88 = .bss:0x80674F88; // type:object size:0x88 +sScreen__Q23EGG16ScreenEffectBase = .bss:0x80674F88; // type:object size:0x88 lbl_80675010 = .bss:0x80675010; // type:object size:0x30 lbl_80675040 = .bss:0x80675040; // type:object size:0x18 data:float lbl_80675058 = .bss:0x80675058; // type:object size:0x18 data:float diff --git a/configure.py b/configure.py index d690c126..e6c5184d 100644 --- a/configure.py +++ b/configure.py @@ -877,13 +877,15 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggDrawPathDOF.cpp"), Object(NonMatching, "egg/gfx/eggDrawPathUnk2.cpp"), Object(NonMatching, "egg/gfx/eggFog.cpp"), + Object(NonMatching, "egg/gfx/eggFogManager.cpp"), Object(NonMatching, "egg/gfx/eggFrustum.cpp"), Object(NonMatching, "egg/gfx/eggG3DUtility.cpp"), # Unknown Guess Object(NonMatching, "egg/gfx/eggGfxEngine.cpp"), - Object(NonMatching, "egg/gfx/eggGlobalDrawState.cpp"), + Object(Matching, "egg/gfx/eggGlobalDrawState.cpp"), Object(NonMatching, "egg/gfx/eggGXUtility.cpp"), - Object(NonMatching, "egg/gfx/eggIScnProc.cpp"), - Object(NonMatching, "egg/gfx/eggLight.cpp"), + Object(Matching, "egg/gfx/eggIScnProc.cpp"), + Object(NonMatching, "egg/gfx/eggLightManager.cpp"), + Object(NonMatching, "egg/gfx/eggLightObject.cpp"), Object(NonMatching, "egg/gfx/eggLightTexture.cpp"), Object(NonMatching, "egg/gfx/eggLightTextureMgr.cpp"), Object(NonMatching, "egg/gfx/eggModelEx.cpp"), @@ -895,7 +897,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggPostEffectMaskDOF.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectSimple.cpp"), Object(NonMatching, "egg/gfx/eggScreen.cpp"), - Object(NonMatching, "egg/gfx/eggScreenEffectBase.cpp"), + Object(Matching, "egg/gfx/eggScreenEffectBase.cpp"), Object(NonMatching, "egg/gfx/eggScreenEffectBlur.cpp"), # Unknown Guess Object(NonMatching, "egg/gfx/eggStateEfb.cpp"), Object(NonMatching, "egg/gfx/eggStateGX.cpp"), diff --git a/include/egg/gfx/eggFog.h b/include/egg/gfx/eggFog.h index 43f9a8d5..13d1bb94 100644 --- a/include/egg/gfx/eggFog.h +++ b/include/egg/gfx/eggFog.h @@ -1,26 +1,46 @@ #ifndef EGG_FOG_H #define EGG_FOG_H +#include "common.h" #include "egg/prim/eggBinary.h" +#include "nw4r/g3d/g3d_fog.h" #include "nw4r/types_nw4r.h" +#include "rvl/GX/GXTypes.h" namespace EGG { -// TODO: Add members -class FogManager : IBinary { +class Fog : public IBinary { public: - FogManager(u16); - virtual ~FogManager(); - virtual void SetBinaryInner(Bin &) override; + struct BinData { + /* 0x10 */ f32 mStartZ; + /* 0x14 */ f32 mEndZ; + /* 0x18 */ f32 mNearZ; + /* 0x1C */ f32 mFarZ; + /* 0x20 */ GXColor mColor; + /* 0x24 */ u8 field_0x24; + /* 0x25 */ u8 mFlag2; + /* 0x26 */ u16 field_0x26; + /* 0x28 */ UNKWORD field_0x28; + /* 0x2C */ UNKWORD field_0x2C; + }; + Fog(); + virtual ~Fog(); + virtual void SetBinaryInner(const Bin &) override; virtual void GetBinaryInner(Bin *) const override; - virtual size_t GetBinarySize() override; virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; - void Calc(); - void CopyToG3D(nw4r::g3d::ScnRoot *) const; + void CopyToG3D(nw4r::g3d::Fog fof) const; + void Reset(); - /* 0x04 */ u8 mFlag; - /* 0x05 */ u8 TODO[0x10 - 0x05]; +private: + + /* 0x04 */ GXColor mColor; + /* 0x08 */ f32 mStartZ; + /* 0x0C */ f32 mEndZ; + /* 0x10 */ f32 mNearZ; + /* 0x14 */ f32 mFarZ; + /* 0x18 */ GXFogType mFogType; + /* 0x1C */ u8 mFlags; }; } // namespace EGG diff --git a/include/egg/gfx/eggFogManager.h b/include/egg/gfx/eggFogManager.h new file mode 100644 index 00000000..589b5041 --- /dev/null +++ b/include/egg/gfx/eggFogManager.h @@ -0,0 +1,44 @@ +#ifndef EGG_FOG_MANAGER_H +#define EGG_FOG_MANAGER_H + +#include "common.h" +#include "egg/gfx/eggFog.h" +#include "egg/prim/eggBinary.h" +#include "nw4r/types_nw4r.h" + +namespace EGG { + +// TODO: Add members +class FogManager : IBinary { +public: + struct BinData { + /* 0x10 */ u16 mCount; + /* 0x12 */ u8 _0x12[2]; + /* 0x14 */ IBinary::Bin mFogData[1]; + }; + FogManager(u16); + virtual ~FogManager(); + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual size_t GetBinarySize() const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + + void ResetFog(); + void Calc(); + void CopyToG3D(nw4r::g3d::ScnRoot *) const; + + void DoneDraw() { + mFlag &= ~4; + } + +private: + /* 0x04 */ u8 mFlag; + /* 0x05 */ u8 TODO[0x08 - 0x05]; + /* 0x08 */ u16 mCount; + /* 0x0A */ u16 mCount2; + /* 0x0C */ Fog *mpFog; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggG3DUtility.h b/include/egg/gfx/eggG3DUtility.h index 994b7376..059261c7 100644 --- a/include/egg/gfx/eggG3DUtility.h +++ b/include/egg/gfx/eggG3DUtility.h @@ -1,6 +1,20 @@ #ifndef EGG_G3D_UTILITY_H #define EGG_G3D_UTILITY_H -namespace EGG {} // namespace EGG +#include "rvl/MEM/mem_allocator.h" + +namespace EGG { + +class G3DUtility { +public: + static MEMAllocator *getAllocator() { + return sAllocator; + } + +private: + static MEMAllocator *sAllocator; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggGlobalDrawState.h b/include/egg/gfx/eggGlobalDrawState.h index 36e5203a..11c070ec 100644 --- a/include/egg/gfx/eggGlobalDrawState.h +++ b/include/egg/gfx/eggGlobalDrawState.h @@ -1,6 +1,26 @@ #ifndef EGG_GLOBAL_DRAW_STATE_H #define EGG_GLOBAL_DRAW_STATE_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggScreen.h" +#include "nw4r/math/math_types.h" + +namespace EGG { + +class GlobalDrawState { +public: + GlobalDrawState() {} + static void setDrawSettingGX(bool, bool); + static void beginDrawView(u16, nw4r::math::MTX34 const &, Screen const &); + +private: + static u16 sCameraId; + static u32 sDrawFlag; + static Screen const *spScreen; + + // unknown + static nw4r::math::MTX34 sMtx; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggIScnProc.h b/include/egg/gfx/eggIScnProc.h index c7ef3ce2..7096351c 100644 --- a/include/egg/gfx/eggIScnProc.h +++ b/include/egg/gfx/eggIScnProc.h @@ -1,6 +1,45 @@ #ifndef EGG_ISCNPROC_H #define EGG_ISCNPROC_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "nw4r/g3d/g3d_scnproc.h" +#include "rvl/MEM/mem_allocator.h" + +namespace EGG { + +class IScnProc { +private: + // Unofficial name + struct ProcData { + IScnProc *mpThis; // at 0x0 + nw4r::g3d::ScnProc *mpScnProc; // at 0x4 + u16 mIndex; // at 0x8 + u8 mFlags; // at 0xA + }; + + ProcData *mpDataSet; // at 0x0 + u16 mNumScnProc; // at 0x4 + +public: + IScnProc() : mpDataSet(nullptr), mNumScnProc(0) {} + virtual void doDraw(u16) = 0; // at 0x8 + virtual ~IScnProc(); // at 0xC + + void createScnProc(u16 procNum, MEMAllocator *allocator); + void setPriorityScnProc(u16, u8, bool); + void pushBackToScnGroup(nw4r::g3d::ScnGroup *); + void removeFromScnGroup(nw4r::g3d::ScnGroup *); + static void drawProcFunc(nw4r::g3d::ScnProc *, bool); + static void drawProcFuncNoGlobalState(nw4r::g3d::ScnProc *, bool); + + u16 getNumScnProc() { + return mNumScnProc; + } + ProcData *getData(u16 procIndex) { + return &mpDataSet[procIndex]; + } +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggLight.h b/include/egg/gfx/eggLight.h index 16033dc3..d34d0b5d 100644 --- a/include/egg/gfx/eggLight.h +++ b/include/egg/gfx/eggLight.h @@ -16,10 +16,11 @@ public: // TODO: Fill out more class LightTextureManager : public IBinary { public: + struct BinData {}; virtual ~LightTextureManager(); - virtual void SetBinaryInner(Bin &) override; + virtual void SetBinaryInner(const Bin &) override; virtual void GetBinaryInner(Bin *) const override; - virtual size_t GetBinarySize() override; + virtual size_t GetBinarySize() const override; virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; void replaceModelTextures(nw4r::g3d::ResMdl) const; @@ -29,12 +30,13 @@ public: // TODO: Fill out more class LightManager : public IBinary { public: + struct BinData {}; // vt at 0x00 LightManager(u32, u32, u8); virtual ~LightManager(); - virtual void SetBinaryInner(Bin &) override; + virtual void SetBinaryInner(const Bin &) override; virtual void GetBinaryInner(Bin *) const override; - virtual size_t GetBinarySize() override; + virtual size_t GetBinarySize() const override; virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; virtual void Reset(); virtual void Calc(nw4r::g3d::ScnRoot *); diff --git a/include/egg/gfx/eggScreenEffectBase.h b/include/egg/gfx/eggScreenEffectBase.h index 447b328d..d2c25d15 100644 --- a/include/egg/gfx/eggScreenEffectBase.h +++ b/include/egg/gfx/eggScreenEffectBase.h @@ -1,6 +1,23 @@ #ifndef EGG_SCREEN_EFFECT_BASE_H #define EGG_SCREEN_EFFECT_BASE_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggScreen.h" + +namespace EGG { + +class ScreenEffectBase { +private: + u8 mFlag; + +public: + ScreenEffectBase(); + virtual ~ScreenEffectBase() {} // at 0x8 + +protected: + static Screen sScreen; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggStateEfb.h b/include/egg/gfx/eggStateEfb.h index 5590f9c7..fdecd35a 100644 --- a/include/egg/gfx/eggStateEfb.h +++ b/include/egg/gfx/eggStateEfb.h @@ -1,6 +1,13 @@ #ifndef EGG_STATE_EFB_H #define EGG_STATE_EFB_H -namespace EGG {} // namespace EGG +namespace EGG { + +class StateEfb { +public: + static void Clean(); +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggStateGX.h b/include/egg/gfx/eggStateGX.h index 7351416c..3c1dce73 100644 --- a/include/egg/gfx/eggStateGX.h +++ b/include/egg/gfx/eggStateGX.h @@ -27,6 +27,11 @@ public: static void invalidateTexAllGX(); + static bool GXSetColorUpdate_(bool); + static bool GXSetAlphaUpdate_(bool); + static bool GXSetDither_(bool); + static bool GXSetDstAlpha_(bool, u8); + static bool GXSetColorUpdate(bool); static bool GXSetAlphaUpdate(bool); static bool GXSetDither(); @@ -38,6 +43,9 @@ public: static void GXSetViewport(f32, f32, f32, f32, f32, f32); static void GZSetScissor(u32, u32, u32, u32); static void GZSetScissorBoxOffset(s32, s32); + + + static u16 s_commandFlag; }; } // namespace EGG diff --git a/include/egg/prim/eggBinary.h b/include/egg/prim/eggBinary.h index 067bf8c1..990bd03c 100644 --- a/include/egg/prim/eggBinary.h +++ b/include/egg/prim/eggBinary.h @@ -3,23 +3,88 @@ #include "common.h" +namespace EGG { + +/** + * @brief Common interface for objects that can be serialized to + * and deserializized from binary. + * + * @tparam T The type of the Egg class. Must have a BinData type + * that describes the binary type. + */ template class IBinary { public: - class Bin {}; - virtual void SetBinaryInner(Bin &) = 0; +#pragma pack(push, 1) + struct BinHeader { + /* 0x00 */ char mType[4]; + /* 0x04 */ size_t mSize; + /* 0x08 */ u8 mVersion; + /* 0x09 */ u16 field_0x09; + /* 0x0B */ u8 field_0x0B; + /* 0x0C */ u32 field_0x0C; + }; + struct Bin { + BinHeader mHeader; + typename T::BinData mData; + }; +#pragma pack(pop) + +protected: + /** Load the object from binary */ + virtual void SetBinaryInner(const Bin &) = 0; + /** Save the object to binary */ virtual void GetBinaryInner(Bin *) const = 0; - virtual size_t GetBinarySize() = 0; + /** Get the size of the serialized data. Override if your binary has a dynamic size */ + virtual size_t GetBinarySize() const { + return sizeof(Bin); + } + /** Load the object from binary, interpolating between values */ virtual void SetBinaryInner(const Bin &, const Bin &, f32) = 0; + /** Get a 4-bytes long ID string corresponding to this type */ static const char *GetBinaryType(); - int GetVersion(); - - void GetBinary(void *) const; + /** Get the current version of this type */ + static int GetVersion(); +public: + // These functions below are automatically provided, you should not need to + // touch them to implement de-/serialization for your type. They will parse + // the binary header and then invoke the above virtual functions. + void GetBinary(void *pData) const; void SetBinary(const void *); - - void SetBinaryBlend(const void *, const void *, f32); + void SetBinaryBlend(const void *a, const void *b, f32 blend); }; +template +void IBinary::GetBinary(void *pData) const { + Bin *pBin = reinterpret_cast(pData); + BinHeader zeroedHeader = {0}; + pBin->mHeader = zeroedHeader; + + pBin->mHeader.mVersion = GetVersion(); + pBin->mHeader.mSize = GetBinarySize(); + for (int i = 0; i < 4; i++) { + pBin->mHeader.mType[i] = GetBinaryType()[i]; + } + typename T::BinData zeroedDatat = {0}; + pBin->mData = zeroedDatat; + GetBinaryInner(pBin); +} + +template +void IBinary::SetBinary(const void *a) { + const Bin *pBinA = reinterpret_cast(a); + SetBinaryInner(*pBinA); +} + +template +void IBinary::SetBinaryBlend(const void *a, const void *b, f32 blend) { + const Bin *pBinA = reinterpret_cast(a); + const Bin *pBinB = reinterpret_cast(b); + SetBinaryInner(*pBinA, *pBinB, blend); +} + +} // namespace EGG + #endif diff --git a/include/m/m3d/m3d.h b/include/m/m3d/m3d.h index f994db04..e1503ecf 100644 --- a/include/m/m3d/m3d.h +++ b/include/m/m3d/m3d.h @@ -2,7 +2,7 @@ #define M3D_H #include "egg/core/eggHeap.h" -#include "egg/gfx/eggFog.h" +#include "egg/gfx/eggFogManager.h" #include "egg/gfx/eggLight.h" #include "m/m_allocator.h" #include "nw4r/g3d/g3d_scnroot.h" diff --git a/include/nw4r/g3d/g3d_fog.h b/include/nw4r/g3d/g3d_fog.h index 417198d3..7cbe9e00 100644 --- a/include/nw4r/g3d/g3d_fog.h +++ b/include/nw4r/g3d/g3d_fog.h @@ -76,6 +76,13 @@ public: bool IsFogRangeAdjEnable() const { return IsValid() && ref().adjEnable == TRUE; } + + void SetFogRangeAdjEnable(bool enable) { + if (!IsValid()) { + return; + } + ref().adjEnable = enable; + } }; } // namespace g3d diff --git a/src/egg/gfx/eggFog.cpp b/src/egg/gfx/eggFog.cpp index 71bf0b8c..4669c270 100644 --- a/src/egg/gfx/eggFog.cpp +++ b/src/egg/gfx/eggFog.cpp @@ -1,3 +1,68 @@ #include "egg/gfx/eggFog.h" -namespace EGG {} // namespace EGG +#include "egg/egg_types.h" +#include "egg/gfx/eggDrawGX.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +template <> +const char *IBinary::GetBinaryType() { + return "FOGD"; +} + +template <> +int IBinary::GetVersion() { + return 0; +} + +Fog::Fog() { + Reset(); +} + +void Fog::Reset() { + // TODO + mColor = DrawGX::WHITE; + mNearZ = 0.0f; + mFarZ = 0.0f; + mEndZ = 0.0f; + mStartZ = 0.0f; + mFogType = GX_FOG_NONE; + mFlags = 0; +} + +void Fog::CopyToG3D(nw4r::g3d::Fog fog) const { + fog.SetFogType((mFlags & 1) ? mFogType : GX_FOG_NONE); + fog.SetZ(mStartZ, mEndZ); + fog.SetFogColor(mColor); + fog.SetFogRangeAdjEnable(mFlags & 2); +} + +void Fog::SetBinaryInner(const Bin &bin) { + if (bin.mHeader.mVersion != 0) { + return; + } + mStartZ = bin.mData.mStartZ; + mEndZ = bin.mData.mEndZ; + mNearZ = bin.mData.mNearZ; + mFarZ = bin.mData.mFarZ; + mColor = bin.mData.mColor; + mFogType = (GXFogType)bin.mData.field_0x24; + mFlags = bin.mData.mFlag2; +} + +void Fog::GetBinaryInner(Bin *pBin) const { + pBin->mData.mStartZ = mStartZ; + pBin->mData.mEndZ = mEndZ; + pBin->mData.mNearZ = mNearZ; + pBin->mData.mFarZ = mFarZ; + pBin->mData.mColor = mColor; + pBin->mData.field_0x24 = mFogType; + pBin->mData.mFlag2 = mFlags; +} + +void Fog::SetBinaryInner(const Bin &, const Bin &, f32) {} + +Fog::~Fog() {} + +} // namespace EGG diff --git a/src/egg/gfx/eggFogManager.cpp b/src/egg/gfx/eggFogManager.cpp new file mode 100644 index 00000000..44d504fb --- /dev/null +++ b/src/egg/gfx/eggFogManager.cpp @@ -0,0 +1,69 @@ +#include "egg/gfx/eggFogManager.h" + +#include "common.h" +#include "nw4r/g3d/g3d_scnroot.h" + + +namespace EGG { + +FogManager::FogManager(u16 num) : mFlag(0), mCount(num), mCount2(num) { + mpFog = new Fog[num]; +} + +FogManager::~FogManager() { + delete[] mpFog; +} + +void FogManager::ResetFog() { + for (int i = 0; i < mCount; i++) { + mpFog[i].Reset(); + } +} + +void FogManager::Calc() { + if (!(mFlag & 4)) { + mFlag |= 4; + } +} + +void FogManager::CopyToG3D(nw4r::g3d::ScnRoot *root) const { + for (int i = 0; i < mCount; i++) { + mpFog[i].CopyToG3D(root->GetFog(i)); + } +} + +void FogManager::SetBinaryInner(const Bin &bin) { + if (bin.mHeader.mVersion == 0) { + u32 loopMax = bin.mData.mCount >= mCount2 ? mCount2 : bin.mData.mCount; + const IBinary::Bin *pBinData = bin.mData.mFogData; + for (u16 i = 0; i < loopMax; i++) { + mpFog[i].SetBinary(&pBinData[i]); + } + } +} + +void FogManager::SetBinaryInner(const Bin &bin1, const Bin &bin2, f32 blend) { + if (bin1.mHeader.mVersion == 0) { + u32 loopMax = bin1.mData.mCount >= mCount2 ? mCount2 : bin1.mData.mCount; + const IBinary::Bin *pBinData1 = bin1.mData.mFogData; + const IBinary::Bin *pBinData2 = bin2.mData.mFogData; + for (u16 i = 0; i < loopMax; i++) { + mpFog[i].SetBinaryBlend(&pBinData1[i], &pBinData2[i], blend); + } + } +} + +void FogManager::GetBinaryInner(Bin *pOutBin) const { + pOutBin->mData.mCount = mCount2; + u16 max = mCount2; + IBinary::Bin *pOutData = pOutBin->mData.mFogData; + for (u16 i = 0; i < max; i++) { + mpFog[i].GetBinary(&pOutData[i]); + } +} + +size_t FogManager::GetBinarySize() const { + return sizeof(Bin) + (mCount2 - 1) * sizeof(Fog::Bin); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggGlobalDrawState.cpp b/src/egg/gfx/eggGlobalDrawState.cpp index aed5311a..12a37a32 100644 --- a/src/egg/gfx/eggGlobalDrawState.cpp +++ b/src/egg/gfx/eggGlobalDrawState.cpp @@ -1,3 +1,37 @@ #include "egg/gfx/eggGlobalDrawState.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggStateEfb.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +Screen const *GlobalDrawState::spScreen; +u16 GlobalDrawState::sCameraId; +u32 GlobalDrawState::sDrawFlag; + +// unknown +nw4r::math::MTX34 GlobalDrawState::sMtx; + +GlobalDrawState sState; + +void GlobalDrawState::beginDrawView(u16 cameraId, const nw4r::math::MTX34 &mtx, const Screen &screen) { + spScreen = &screen; + sCameraId = cameraId; + PSMTXCopy(mtx, sMtx); + StateEfb::Clean(); +} + +void GlobalDrawState::setDrawSettingGX(bool b1, bool b2) { + StateGX::GXSetColorUpdate_(sDrawFlag & 1); + StateGX::GXSetAlphaUpdate_(sDrawFlag & 2); + StateGX::GXSetDither_(sDrawFlag & 4); + StateGX::GXSetDstAlpha_(false, 0); + if (b2 && spScreen != nullptr) { + spScreen->SetProjectionGX(); + } +} + + +} // namespace EGG diff --git a/src/egg/gfx/eggIScnProc.cpp b/src/egg/gfx/eggIScnProc.cpp index 6b86ce5b..e293cc91 100644 --- a/src/egg/gfx/eggIScnProc.cpp +++ b/src/egg/gfx/eggIScnProc.cpp @@ -1,3 +1,88 @@ #include "egg/gfx/eggIScnProc.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggG3DUtility.h" +#include "egg/gfx/eggGlobalDrawState.h" +#include "egg/gfx/eggStateGX.h" +#include "nw4r/g3d/g3d_scnobj.h" +#include "nw4r/math/math_types.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +IScnProc::~IScnProc() { + if (mpDataSet != nullptr) { + for (int i = 0; i < getNumScnProc(); i++) { + mpDataSet[i].mpScnProc->Destroy(); + mpDataSet[i].mpScnProc = nullptr; + } + + delete[] mpDataSet; + mpDataSet = nullptr; + } +} + +void IScnProc::createScnProc(u16 procNum, MEMAllocator *pAllocator) { + mNumScnProc = procNum; + mpDataSet = new ProcData[mNumScnProc]; + nw4r::math::MTX34 mtx; + PSMTXIdentity(mtx); + + for (u16 i = 0; i < getNumScnProc(); i++) { + u32 sp8; + MEMAllocator *allocator = (pAllocator == nullptr) ? G3DUtility::getAllocator() : pAllocator; + + mpDataSet[i].mpScnProc = nw4r::g3d::ScnProc::Construct(allocator, &sp8, IScnProc::drawProcFunc, true, false, 0); + + mpDataSet[i].mpScnProc->SetUserData(&mpDataSet[i]); + mpDataSet[i].mpScnProc->SetMtx(nw4r::g3d::ScnObj::MTX_LOCAL, mtx); + + mpDataSet[i].mIndex = i; + mpDataSet[i].mpThis = this; + mpDataSet[i].mFlags = 1 | 2; + + setPriorityScnProc(i, i, true); + } +} + +void IScnProc::setPriorityScnProc(u16 procIndex, u8 priority, bool bUseOpa) { + nw4r::g3d::ScnProc *pScnProc = getData(procIndex)->mpScnProc; + if (bUseOpa) { + pScnProc->SetDrawProc(IScnProc::drawProcFunc, true, false); + pScnProc->SetPriorityDrawOpa(priority); + mpDataSet[procIndex].mFlags |= 1; + } else { + pScnProc->SetDrawProc(IScnProc::drawProcFunc, false, true); + pScnProc->SetPriorityDrawXlu(priority); + mpDataSet[procIndex].mFlags &= ~1; + } +} + +void IScnProc::pushBackToScnGroup(nw4r::g3d::ScnGroup *pScnGroup) { + for (u16 i = 0; i < getNumScnProc(); i++) { + bool is_push_back = pScnGroup->Insert(pScnGroup->Size(), getData(i)->mpScnProc); + } +} + +void IScnProc::removeFromScnGroup(nw4r::g3d::ScnGroup *pScnGroup) { + for (u16 i = 0; i < getNumScnProc(); i++) { + bool is_remove = pScnGroup->Remove(getData(i)->mpScnProc); + } +} + +void IScnProc::drawProcFunc(nw4r::g3d::ScnProc *pScnProc, bool b) { + GlobalDrawState::setDrawSettingGX(b, false); + StateGX::s_commandFlag &= ~0xF; + drawProcFuncNoGlobalState(pScnProc, b); + StateGX::resetGXCache(); + + GlobalDrawState::setDrawSettingGX(b, (StateGX::s_commandFlag & 0xF) != 0); +} + +void IScnProc::drawProcFuncNoGlobalState(nw4r::g3d::ScnProc *pScnProc, bool b) { + ProcData *dat = static_cast(pScnProc->GetUserData()); + dat->mpThis->doDraw(dat->mIndex); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggLight.cpp b/src/egg/gfx/eggLightManager.cpp similarity index 100% rename from src/egg/gfx/eggLight.cpp rename to src/egg/gfx/eggLightManager.cpp diff --git a/src/egg/gfx/eggLightObject.cpp b/src/egg/gfx/eggLightObject.cpp new file mode 100644 index 00000000..c842a6ec --- /dev/null +++ b/src/egg/gfx/eggLightObject.cpp @@ -0,0 +1,3 @@ +#include "egg/gfx/eggLight.h" + +namespace EGG {} // namespace EGG diff --git a/src/egg/gfx/eggScreenEffectBase.cpp b/src/egg/gfx/eggScreenEffectBase.cpp index 6e8a1f55..890c7106 100644 --- a/src/egg/gfx/eggScreenEffectBase.cpp +++ b/src/egg/gfx/eggScreenEffectBase.cpp @@ -1,3 +1,9 @@ #include "egg/gfx/eggScreenEffectBase.h" -namespace EGG {} // namespace EGG +namespace EGG { + +Screen ScreenEffectBase::sScreen; + +ScreenEffectBase::ScreenEffectBase() : mFlag(1) {} + +} // namespace EGG diff --git a/src/m/m3d/m3d.cpp b/src/m/m3d/m3d.cpp index 688be98d..5ccdba26 100644 --- a/src/m/m3d/m3d.cpp +++ b/src/m/m3d/m3d.cpp @@ -180,7 +180,7 @@ void drawDone(int idx) { internal::l_lightMgr_pp[idx]->DoneDraw(); } if (internal::l_fogMgr_pp && internal::l_fogMgr_pp[idx]) { - internal::l_fogMgr_pp[idx]->mFlag &= 0xFB; + internal::l_fogMgr_pp[idx]->DoneDraw(); } } From 8759f710e57f66d035998428b8c864da80e36fd7 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 15 Mar 2025 22:14:01 +0100 Subject: [PATCH 02/62] more --- config/SOUE01/splits.txt | 6 ++ config/SOUE01/symbols.txt | 40 ++++---- configure.py | 2 +- include/egg/gfx/eggCapTexture.h | 22 ++++- include/egg/gfx/eggCpuTexture.h | 131 ++++++++++++++++++++++++- include/egg/gfx/eggDrawPathBase.h | 26 ++++- include/egg/gfx/eggIScnProc.h | 7 +- include/egg/gfx/eggPostEffectBase.h | 32 +++++- include/egg/gfx/eggScreenEffectBase.h | 2 +- include/egg/gfx/eggStateGX.h | 10 +- include/rvl/GX/GXFrameBuf.h | 1 + include/rvl/GX/GXTexture.h | 9 +- src/egg/gfx/eggCapTexture.cpp | 58 ++++++++++- src/egg/gfx/eggCpuTexture.cpp | 134 +++++++++++++++++++++++++- src/egg/gfx/eggDrawPathBase.cpp | 43 ++++++++- src/egg/gfx/eggGlobalDrawState.cpp | 6 +- src/egg/gfx/eggIScnProc.cpp | 2 +- src/egg/gfx/eggPostEffectBase.cpp | 24 ++++- src/toBeSorted/d_d3d.cpp | 2 +- 19 files changed, 511 insertions(+), 46 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 28407b19..02ccf1cf 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2179,9 +2179,14 @@ egg/gfx/eggUnk1.cpp: egg/gfx/eggCapTexture.cpp: .text start:0x8049D7C0 end:0x8049D9D0 + .rodata start:0x804FBA30 end:0x804FBA60 + .data start:0x8056ED70 end:0x8056ED80 + .sdata2 start:0x8057F410 end:0x8057F418 + .sbss2 start:0x8057FFC0 end:0x8057FFC8 egg/gfx/eggCpuTexture.cpp: .text start:0x8049DA30 end:0x8049EC94 + .data start:0x8056ED80 end:0x8056EDA0 egg/gfx/eggDrawGX.cpp: .text start:0x8049ECA0 end:0x804A0C24 @@ -2189,6 +2194,7 @@ egg/gfx/eggDrawGX.cpp: egg/gfx/eggDrawPathBase.cpp: .text start:0x804A0C30 end:0x804A0E98 + .data start:0x8056EE60 end:0x8056EEB0 egg/gfx/eggDrawPathUnk1.cpp: .text start:0x804A0EA0 end:0x804A29B8 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 9b81b258..d743d8d6 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -610,7 +610,7 @@ fn_80019780 = .text:0x80019780; // type:function size:0x6C fn_800197F0 = .text:0x800197F0; // type:function size:0x5C fn_80019850 = .text:0x80019850; // type:function size:0x58 drawXlu__Q23d3d7XluProcFv = .text:0x800198B0; // type:function size:0x17C -EGG__CapTexture____dt = .text:0x80019A30; // type:function size:0x58 +__dt__Q23EGG10CapTextureFv = .text:0x80019A30; // type:function size:0x58 fn_80019A90 = .text:0x80019A90; // type:function size:0x4C fn_80019AE0 = .text:0x80019AE0; // type:function size:0x98 fn_80019B80 = .text:0x80019B80; // type:function size:0x8 @@ -720,7 +720,7 @@ fn_8001F570 = .text:0x8001F570; // type:function size:0x70 fn_8001F5E0 = .text:0x8001F5E0; // type:function size:0x5C fn_8001F640 = .text:0x8001F640; // type:function size:0x40 fn_8001F680 = .text:0x8001F680; // type:function size:0x70 -fn_8001F6F0 = .text:0x8001F6F0; // type:function size:0x4 +ExecCallback_CALC_MAT__Q34nw4r3g3d15IScnObjCallbackFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x8001F6F0; // type:function size:0x4 fn_8001F700 = .text:0x8001F700; // type:function size:0xA8 fn_8001F7B0 = .text:0x8001F7B0; // type:function size:0x64 sprintf__15SizedString<32>FPCce = .text:0x8001F820; // type:function size:0xD0 @@ -9780,7 +9780,7 @@ fn_80171B70 = .text:0x80171B70; // type:function size:0x5C fn_80171BD0 = .text:0x80171BD0; // type:function size:0xA90 fn_80172660 = .text:0x80172660; // type:function size:0x4C fn_801726B0 = .text:0x801726B0; // type:function size:0x218 -EGG__DrawPathBase____dt = .text:0x801728D0; // type:function size:0x5C +__dt__Q23EGG12DrawPathBaseFv = .text:0x801728D0; // type:function size:0x5C __dt__Q23EGG16ScreenEffectBaseFv = .text:0x80172930; // type:function size:0x40 fn_80172970 = .text:0x80172970; // type:function size:0xB4 fn_80172A30 = .text:0x80172A30; // type:function size:0x40 @@ -9790,14 +9790,14 @@ fn_80173FA0 = .text:0x80173FA0; // type:function size:0x128 fn_801740D0 = .text:0x801740D0; // type:function size:0x60 fn_80174130 = .text:0x80174130; // type:function size:0x1D8 fn_80174310 = .text:0x80174310; // type:function size:0x5F0 -fn_80174900 = .text:0x80174900; // type:function size:0x4 +internalResetForDraw__Q23EGG12DrawPathBaseFv = .text:0x80174900; // type:function size:0x4 fn_80174910 = .text:0x80174910; // type:function size:0x8 fn_80174920 = .text:0x80174920; // type:function size:0x4 fn_80174930 = .text:0x80174930; // type:function size:0x8 fn_80174940 = .text:0x80174940; // type:function size:0x14 fn_80174960 = .text:0x80174960; // type:function size:0x8 -fn_80174970 = .text:0x80174970; // type:function size:0x8 -fn_80174980 = .text:0x80174980; // type:function size:0x8 +@8@scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x80174970; // type:function size:0x8 +@20@ExecCallback_CALC_VIEW__Q23EGG12DrawPathBaseFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x80174980; // type:function size:0x8 fn_80174990 = .text:0x80174990; // type:function size:0x8 fn_801749A0 = .text:0x801749A0; // type:function size:0x8 fn_801749B0 = .text:0x801749B0; // type:function size:0x8 @@ -26435,14 +26435,14 @@ calcColorGradient_EGG_CpuTexture_8049da30 = .text:0x8049DA30; // type:function s makeGradient_EGG_CpuTexture_8049dbc0 = .text:0x8049DBC0; // type:function size:0x450 __ct__Q23EGG10CpuTextureFv = .text:0x8049E010; // type:function size:0x44 __ct__Q23EGG10CpuTextureFUsUs9_GXTexFmt = .text:0x8049E060; // type:function size:0x40 -__ct__Q23EGG10CpuTextureFP9_GXTexObj = .text:0x8049E0A0; // type:function size:0xB0 +__ct__Q23EGG10CpuTextureFPC9_GXTexObj = .text:0x8049E0A0; // type:function size:0xB0 __dt__Q23EGG10CpuTextureFv = .text:0x8049E150; // type:function size:0x70 configure__Q23EGG10CpuTextureFv = .text:0x8049E1C0; // type:function size:0xC setBuffer__Q23EGG10CpuTextureFPv = .text:0x8049E1D0; // type:function size:0x1C load__Q23EGG10CpuTextureCF11_GXTexMapID = .text:0x8049E1F0; // type:function size:0x3C getTexObj__Q23EGG10CpuTextureCFP9_GXTexObj = .text:0x8049E230; // type:function size:0x80 flush__Q23EGG10CpuTextureCFv = .text:0x8049E2B0; // type:function size:0x4C -buildHeader_EGG_CpuTexture_8049e300 = .text:0x8049E300; // type:function size:0x84 +buildHeader__Q23EGG10CpuTextureCFv = .text:0x8049E300; // type:function size:0x84 fillNormalMapSphere__EGG_CpuTexture_8049e390 = .text:0x8049E390; // type:function size:0x1BC fillGradient_EGG_CpuTexture_8049e550 = .text:0x8049E550; // type:function size:0x3A8 alloc__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049E900; // type:function size:0x84 @@ -26779,11 +26779,11 @@ resetPE__Q23EGG7StateGXFv = .text:0x804B4EF0; // type:function size:0xB0 resetGXCache__Q23EGG7StateGXFv = .text:0x804B4FA0; // type:function size:0x40 EGG__StateGX__GXSetPixelFmt_ = .text:0x804B4FE0; // type:function size:0xAC invalidateTexAllGX__Q23EGG7StateGXFv = .text:0x804B5090; // type:function size:0x4 -GXSetColorUpdate___Q23EGG7StateGXFb = .text:0x804B50A0; // type:function size:0x4C -GXSetAlphaUpdate___Q23EGG7StateGXFb = .text:0x804B50F0; // type:function size:0x4C -GXSetDither___Q23EGG7StateGXFb = .text:0x804B5140; // type:function size:0x4C -FUN_804b5190 = .text:0x804B5190; // type:function size:0x8 -GXSetDstAlpha___Q23EGG7StateGXFbUc = .text:0x804B51A0; // type:function size:0x4C +GXSetColorUpdate___Q23EGG7StateGXFUc = .text:0x804B50A0; // type:function size:0x4C +GXSetAlphaUpdate___Q23EGG7StateGXFUc = .text:0x804B50F0; // type:function size:0x4C +GXSetDither___Q23EGG7StateGXFUc = .text:0x804B5140; // type:function size:0x4C +GXCopyTex__Q23EGG7StateGXFPvb = .text:0x804B5190; // type:function size:0x8 +GXSetDstAlpha___Q23EGG7StateGXFUcUc = .text:0x804B51A0; // type:function size:0x4C FUN_804b51f0 = .text:0x804B51F0; // type:function size:0x108 FUN_804b5300 = .text:0x804B5300; // type:function size:0x2C GXSetProjectionv___Q23EGG7StateGXFPCf = .text:0x804B5330; // type:function size:0x2C @@ -29159,7 +29159,7 @@ gRMO_Ntsc_640x456Prog_4x3__22@unnamed@eggVideo_cpp@ = .rodata:0x804FB980; // typ gRMO_Ntsc_640x456IntDf_4x3__22@unnamed@eggVideo_cpp@ = .rodata:0x804FB9BC; // type:object size:0x3C scope:local renderModes__3EGG = .rodata:0x804FB9F8; // type:object size:0x28 scope:local @4804 = .rodata:0x804FBA20; // type:object size:0x10 scope:local data:4byte -lbl_804FBA30 = .rodata:0x804FBA30; // type:object size:0x30 +copyArg2__3EGG = .rodata:0x804FBA30; // type:object size:0x30 lbl_804FBA60 = .rodata:0x804FBA60; // type:object size:0xD8 lbl_804FBB38 = .rodata:0x804FBB38; // type:object size:0x30 lbl_804FBB68 = .rodata:0x804FBB68; // type:object size:0xF0 @@ -37355,12 +37355,12 @@ __vt__Q23EGG14CoreController = .data:0x8056EC50; // type:object size:0x38 EGG____OrthoCamera__vtable = .data:0x8056ED00; // type:object size:0x30 EGG__LookAtCamera__vtable = .data:0x8056ED30; // type:object size:0x30 lbl_8056ED60 = .data:0x8056ED60; // type:object size:0x10 -EGG__CapTexture__vtable = .data:0x8056ED70; // type:object size:0x10 -EGG__CpuTexture__vtable = .data:0x8056ED80; // type:object size:0x20 +__vt__Q23EGG10CapTexture = .data:0x8056ED70; // type:object size:0x10 +__vt__Q23EGG10CpuTexture = .data:0x8056ED80; // type:object size:0x20 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 -lbl_8056EE60 = .data:0x8056EE60; // type:object size:0x50 +__vt__Q23EGG12DrawPathBase = .data:0x8056EE60; // type:object size:0x50 lbl_8056EEB0 = .data:0x8056EEB0; // type:object size:0x78 lbl_8056EF28 = .data:0x8056EF28; // type:object size:0x78 lbl_8056EFA0 = .data:0x8056EFA0; // type:object size:0x50 @@ -48011,9 +48011,7 @@ lbl_8057F3FC = .sdata2:0x8057F3FC; // type:object size:0xC lbl_8057F408 = .sdata2:0x8057F408; // type:object size:0x4 data:4byte lbl_8057F40C = .sdata2:0x8057F40C; // type:object size:0x2 data:2byte lbl_8057F40E = .sdata2:0x8057F40E; // type:object size:0x1 data:byte -lbl_8057F410 = .sdata2:0x8057F410; // type:object size:0x4 data:4byte -lbl_8057F414 = .sdata2:0x8057F414; // type:object size:0x2 data:2byte -lbl_8057F416 = .sdata2:0x8057F416; // type:object size:0x1 data:byte +defaultFilter__3EGG = .sdata2:0x8057F410; // type:object size:0x7 data:byte lbl_8057F418 = .sdata2:0x8057F418; // type:object size:0x4 data:float lbl_8057F41C = .sdata2:0x8057F41C; // type:object size:0x4 data:float lbl_8057F420 = .sdata2:0x8057F420; // type:object size:0x8 data:double @@ -48447,7 +48445,7 @@ lbl_8057FFA0 = .sbss2:0x8057FFA0; // type:object size:0x8 data:4byte lbl_8057FFA8 = .sbss2:0x8057FFA8; // type:object size:0x8 lbl_8057FFB0 = .sbss2:0x8057FFB0; // type:object size:0x8 DefaultBlackColor = .sbss2:0x8057FFB8; // type:object size:0x8 scope:local data:2byte -lbl_8057FFC0 = .sbss2:0x8057FFC0; // type:object size:0x8 data:byte +sBlack__3EGG = .sbss2:0x8057FFC0; // type:object size:0x8 data:byte lbl_8057FFC8 = .sbss2:0x8057FFC8; // type:object size:0x4 lbl_80580000 = .bss:0x80580000; // type:object size:0x14 data:4byte lbl_80580014 = .bss:0x80580014; // type:object size:0xC diff --git a/configure.py b/configure.py index e6c5184d..69f286ad 100644 --- a/configure.py +++ b/configure.py @@ -872,7 +872,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggCapTexture.cpp"), Object(NonMatching, "egg/gfx/eggCpuTexture.cpp"), Object(NonMatching, "egg/gfx/eggDrawGX.cpp"), - Object(NonMatching, "egg/gfx/eggDrawPathBase.cpp"), + Object(Matching, "egg/gfx/eggDrawPathBase.cpp"), Object(NonMatching, "egg/gfx/eggDrawPathUnk1.cpp"), Object(NonMatching, "egg/gfx/eggDrawPathDOF.cpp"), Object(NonMatching, "egg/gfx/eggDrawPathUnk2.cpp"), diff --git a/include/egg/gfx/eggCapTexture.h b/include/egg/gfx/eggCapTexture.h index 6fea561c..9f28a786 100644 --- a/include/egg/gfx/eggCapTexture.h +++ b/include/egg/gfx/eggCapTexture.h @@ -1,6 +1,26 @@ #ifndef EGG_CAP_TEXTURE_H #define EGG_CAP_TEXTURE_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggCpuTexture.h" +#include "rvl/GX/GXTypes.h" +namespace EGG { + +struct CopyFilter { + u8 values[7]; +}; + +class CapTexture : public CpuTexture { + virtual void configure() override; // at 0xC + + void capture(u16 x, u16 y, bool upscale, int format); + +private: + /* 0x18 */ u8 mCapFlags; + /* 0x19 */ GXColor mClearColor; + /* 0x20 */ u32 field_0x20; + /* 0x24 */ CopyFilter mCopyFilterArg; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggCpuTexture.h b/include/egg/gfx/eggCpuTexture.h index c63c6852..9a9418da 100644 --- a/include/egg/gfx/eggCpuTexture.h +++ b/include/egg/gfx/eggCpuTexture.h @@ -1,13 +1,142 @@ #ifndef EGG_CPU_TEXTURE_H #define EGG_CPU_TEXTURE_H +#include "common.h" +#include "egg/core/eggHeap.h" #include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + namespace EGG { class CpuTexture { + void makeGradient(UNKTYPE); public: - void GetTexObj(GXTexObj *) const; + struct Header { + u8 mTexFormat; + u8 BYTE_0x1; + u16 mWidth; + u16 mHeight; + u8 mWrapS; + u8 mWrapT; + u8 BYTE_0x8; + u8 BYTE_0x9; + u16 SHORT_0xA; + u32 WORD_0xC; + u8 BYTE_0xD; + u8 BYTE_0xE; + u8 BYTE_0xF; + u8 BYTE_0x10; + u8 mMinFilt; + u8 mMagFilt; + u8 BYTE_0x13; + u8 BYTE_0x14; + u8 BYTE_0x15; + u16 SHORT_0x16; + u32 WORD_0x18; + }; + + enum TexFlag { + CONFIGURED = 0x1, + HAS_HEADER = 0x2, + NEEDS_BUFFER_FREE = 0x4, + }; + + virtual ~CpuTexture(); // at 0x8 + virtual void configure(); // at 0xC + + void getTexObj(GXTexObj *) const; // at 0x10 + void load(GXTexMapID) const; // at 0x14 + + CpuTexture(); + CpuTexture(u16 width, u16 height, GXTexFmt texFmt); + CpuTexture(const GXTexObj *pObj); + + void checkTexBuffer() const; + void invalidate() const; + void flush() const; + void alloc(Heap *heap); + void allocWithHeaderDebug(Heap *heap); + void allocate(Heap *heap); + + u32 getTexBufferSize() const; + void buildHeader() const; + Header *initHeader(); + void fillNormalMapSphere(); + UNKTYPE func_80086C8C(UNKTYPE); + void allocTexBuffer(); + void allocTexBufferAndHeader(); + void setColor(u16, u16, GXColor); + + bool checkIsConfigure() const { + return mFlags & CONFIGURED; + } + bool checkHasHeader() const { + return mFlags & HAS_HEADER; + } + + void setFlag(u8 flag) { + mFlags |= flag; + } + void clearFlag(u8 flag) { + mFlags &= ~flag; + } + + u16 getWidth() const { + return mWidth; + } + void setWidth(u16 w) { + mWidth = w; + } + + u16 getHeight() const { + return mHeight; + } + void setHeight(u16 h) { + mHeight = h; + } + + GXTexFmt getFormat() const { + return (GXTexFmt)mTexFormat; + } + void setFormat(GXTexFmt fmt) { + mTexFormat = fmt; + } + + void setWrapS(GXTexWrapMode wrap) { + mWrapS = wrap; + } + void setWrapT(GXTexWrapMode wrap) { + mWrapT = wrap; + } + void setMinFilt(GXTexFilter filt) { + mMinFilt = filt; + } + void setMagFilt(GXTexFilter filt) { + mMagFilt = filt; + } + + Header *getHeader() const { + return (Header *)((u8 *)dataPtr - sizeof(Header)); + } + + char *getBuffer() const { + return mpBuffer; + } + void setBuffer(void *pBuffer); + +protected: + u16 mWidth; // at 0x4 + u16 mHeight; // at 0x6 + u8 mFlags; // at 0x8 + u8 mTexFormat; // at 0x9 + u8 mWrapS; // at 0xA + u8 mWrapT; // at 0xB + u8 mMinFilt; // at 0xC + u8 mMagFilt; // at 0xD + u8 UNK_0xE[2]; + void *dataPtr; // at 0x10 + char *mpBuffer; // at 0x14 }; } // namespace EGG diff --git a/include/egg/gfx/eggDrawPathBase.h b/include/egg/gfx/eggDrawPathBase.h index 536864b3..8925785b 100644 --- a/include/egg/gfx/eggDrawPathBase.h +++ b/include/egg/gfx/eggDrawPathBase.h @@ -1,6 +1,30 @@ #ifndef EGG_DRAW_PATH_BASE_H #define EGG_DRAW_PATH_BASE_H -namespace EGG {} // namespace EGG +#include "egg/egg_types.h" +#include "egg/gfx/eggIScnProc.h" +#include "egg/gfx/eggScreenEffectBase.h" +#include "nw4r/g3d/g3d_scnobj.h" + +namespace EGG { + +class DrawPathBase : public ScreenEffectBase, public IScnProc, public nw4r::g3d::IScnObjCallback { +public: + DrawPathBase(); + + void createScnProc(MEMAllocator *allocator); + +protected: + virtual u16 getNumStep() const = 0; // at 0x3C + virtual void internalResetForDraw() {} // at 0x40 + virtual void internalDraw() = 0; // at 0x44 + + virtual void ExecCallback_CALC_VIEW( + nw4r::g3d::ScnObj::Timing /* timing */, nw4r::g3d::ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */ + ) override; // also at 0x48 + virtual void scnProcDraw(u16) override; // also at 0x4C +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggIScnProc.h b/include/egg/gfx/eggIScnProc.h index 7096351c..9d033f43 100644 --- a/include/egg/gfx/eggIScnProc.h +++ b/include/egg/gfx/eggIScnProc.h @@ -8,7 +8,7 @@ namespace EGG { class IScnProc { -private: +protected: // Unofficial name struct ProcData { IScnProc *mpThis; // at 0x0 @@ -22,7 +22,7 @@ private: public: IScnProc() : mpDataSet(nullptr), mNumScnProc(0) {} - virtual void doDraw(u16) = 0; // at 0x8 + virtual void scnProcDraw(u16) = 0; // at 0x8 virtual ~IScnProc(); // at 0xC void createScnProc(u16 procNum, MEMAllocator *allocator); @@ -38,6 +38,9 @@ public: ProcData *getData(u16 procIndex) { return &mpDataSet[procIndex]; } + nw4r::g3d::ScnProc *getProc(u16 procIndex) { + return mpDataSet[procIndex].mpScnProc; + } }; } // namespace EGG diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index 2c7fa0b9..2133c646 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -1,6 +1,36 @@ #ifndef EGG_POST_EFFECT_BASE_H #define EGG_POST_EFFECT_BASE_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggCapTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class PostEffectBase { +protected: + u32 field_0x00; // at 0x0 + CapTexture *mpCapTexture; // at 0x4 + GXTexMapID mTexMapId; // at 0x8 + CapTexture *mpCapTexture2; // at 0xC + GXTexMapID mTexMapId2; // at 0x10 + f32 mOffsetX; // at 0x14 + f32 mOffsetY; // at 0x18 + f32 mScaleX; // at 0x1C + f32 mScaleY; // at 0x20 + f32 field_0x24; // at 0x24 + + PostEffectBase(); + virtual ~PostEffectBase() {} // at 0x8 + +protected: + virtual void draw(f32, f32); // at 0xC + virtual void setMaterialInternal(); // at 0x10 + virtual void loadTextureInternal(); // at 0x14 + virtual void drawScreenInternal(f32, f32, f32, f32); // at 0x18 +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggScreenEffectBase.h b/include/egg/gfx/eggScreenEffectBase.h index d2c25d15..b90c4df7 100644 --- a/include/egg/gfx/eggScreenEffectBase.h +++ b/include/egg/gfx/eggScreenEffectBase.h @@ -7,7 +7,7 @@ namespace EGG { class ScreenEffectBase { -private: +protected: u8 mFlag; public: diff --git a/include/egg/gfx/eggStateGX.h b/include/egg/gfx/eggStateGX.h index 3c1dce73..1d15ad01 100644 --- a/include/egg/gfx/eggStateGX.h +++ b/include/egg/gfx/eggStateGX.h @@ -27,15 +27,15 @@ public: static void invalidateTexAllGX(); - static bool GXSetColorUpdate_(bool); - static bool GXSetAlphaUpdate_(bool); - static bool GXSetDither_(bool); - static bool GXSetDstAlpha_(bool, u8); + static GXBool GXSetColorUpdate_(GXBool); + static GXBool GXSetAlphaUpdate_(GXBool); + static GXBool GXSetDither_(GXBool); + static GXBool GXSetDstAlpha_(GXBool, u8); static bool GXSetColorUpdate(bool); static bool GXSetAlphaUpdate(bool); static bool GXSetDither(); - static void GXCopyTex(); + static void GXCopyTex(void *data, bool); static bool GXSetDstAlpha(); // Unk func here static void GXSetProjection(Mtx44, int); diff --git a/include/rvl/GX/GXFrameBuf.h b/include/rvl/GX/GXFrameBuf.h index 774e6fb8..5ee0b888 100644 --- a/include/rvl/GX/GXFrameBuf.h +++ b/include/rvl/GX/GXFrameBuf.h @@ -29,6 +29,7 @@ u16 GXGetNumXfbLines(u16 height, f32 scale); void GXSetDispCopyDst(u16 width, u16 height); u32 GXSetDispCopyYScale(f32 scale); void GXCopyDisp(void *data, GXBool bUpdate); +void GXSetCopyClamp(int val); // TODO void GXSetTexCopySrc(u16 left, u16 top, u16 width, u16 height); void GXSetTexCopyDst(u16 left, u16 top, GXTexFmt fmt, u8 mipmap); diff --git a/include/rvl/GX/GXTexture.h b/include/rvl/GX/GXTexture.h index 9fbbdace..fcce31ed 100644 --- a/include/rvl/GX/GXTexture.h +++ b/include/rvl/GX/GXTexture.h @@ -48,9 +48,12 @@ u16 GXGetTexObjWidth(const GXTexObj *obj); u16 GXGetTexObjHeight(const GXTexObj *obj); GXTexFmt GXGetTexObjFormat(const GXTexObj *obj); GXBool GXGetTexObjMipMap(const GXTexObj *obj); -GXTexWrapMode GXGetTexObjWrapS(GXTexObj *obj); -u32 GXGetTexObjTlut(GXTexObj *); -GXTexWrapMode GXGetTexObjWrapT(GXTexObj *obj); +GXTexWrapMode GXGetTexObjWrapS(const GXTexObj *obj); +u32 GXGetTexObjTlut(const GXTexObj *); +GXTexWrapMode GXGetTexObjWrapT(const GXTexObj *); +GXTexFilter GXGetTexObjMinFilt(const GXTexObj *); +GXTexFilter GXGetTexObjMagFilt(const GXTexObj *); +void *GXGetTexObjData(const GXTexObj *); u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool arg3, u8 arg4); void GXInvalidateTexAll(); diff --git a/src/egg/gfx/eggCapTexture.cpp b/src/egg/gfx/eggCapTexture.cpp index d2779ce3..166275ae 100644 --- a/src/egg/gfx/eggCapTexture.cpp +++ b/src/egg/gfx/eggCapTexture.cpp @@ -1,3 +1,59 @@ #include "egg/gfx/eggCapTexture.h" -namespace EGG {} // namespace EGG +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/GX/GXFrameBuf.h" +#include "rvl/GX/GXPixel.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +static const GXColor sBlack = {0, 0, 0, 0}; +static const CopyFilter defaultFilter = { + {0, 0, 1, 0x3F, 0, 0, 0} +}; + +static const u8 copyArg2[12][2] = {}; + +void CapTexture::configure() { + CpuTexture::configure(); + mCapFlags = 0; + mClearColor = sBlack; + field_0x20 = 0xFFFFFF; + mCopyFilterArg = defaultFilter; +} + +void CapTexture::capture(u16 x, u16 y, bool upscale, int format) { + GXTexFmt fmt = format == -1 ? getFormat() : static_cast(format); + u16 width = upscale ? getWidth() * 2 : getWidth(); + u16 height = upscale ? getHeight() * 2 : getHeight(); + + GXSetTexCopySrc(x, y, width, height); + GXSetTexCopyDst(mWidth, mHeight, fmt, upscale); + + GXSetCopyFilter( + 0, copyArg2, (mCapFlags & 8) ? true : false, (mCapFlags & 8) ? mCopyFilterArg.values : defaultFilter.values + ); + + // Regswap, grr + GXBool prevColorUpdate = StateGX::GXSetColorUpdate_((mCapFlags & 1) != 0); + GXBool prevAlphaUpdate = StateGX::GXSetAlphaUpdate_((mCapFlags & 2) != 0); + GXSetZMode(true, GX_ALWAYS, (mCapFlags & 4) != 0); + GXSetCopyClear(mClearColor, field_0x20); + GXSetCopyClamp(3); + StateGX::GXCopyTex(dataPtr, true); + GXSetCopyFilter(0, copyArg2, 0, defaultFilter.values); + + if ((mCapFlags & 0x10) != 0) { + GXPixModeSync(); + } + + if ((mCapFlags & 0x20) != 0) { + StateGX::invalidateTexAllGX(); + } + + StateGX::GXSetAlphaUpdate_(prevAlphaUpdate); + StateGX::GXSetColorUpdate_(prevColorUpdate); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggCpuTexture.cpp b/src/egg/gfx/eggCpuTexture.cpp index 674d190b..e6b3322a 100644 --- a/src/egg/gfx/eggCpuTexture.cpp +++ b/src/egg/gfx/eggCpuTexture.cpp @@ -1,3 +1,135 @@ #include "egg/gfx/eggCpuTexture.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggHeap.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/OS/OSCache.h" + +namespace EGG { + +CpuTexture::CpuTexture() { + mWidth = 0; + mHeight = 0; + mFlags = 0; + mTexFormat = GX_TF_RGBA8; + mWrapS = 0; + mWrapT = 0; + mMinFilt = 1; + mMagFilt = 1; + dataPtr = nullptr; + mpBuffer = nullptr; +} + +CpuTexture::CpuTexture(u16 width, u16 height, GXTexFmt texFmt) { + mWidth = width; + mHeight = height; + mFlags = 0; + mTexFormat = texFmt; + mWrapS = 0; + mWrapT = 0; + mMinFilt = 1; + mMagFilt = 1; + dataPtr = nullptr; + mpBuffer = nullptr; +} + +CpuTexture::CpuTexture(const GXTexObj *pObj) { + mWidth = GXGetTexObjWidth(pObj); + mHeight = GXGetTexObjHeight(pObj); + + mTexFormat = GXGetTexObjFormat(pObj); + mWrapS = GXGetTexObjWrapS(pObj); + mWrapT = GXGetTexObjWrapT(pObj); + mMinFilt = GXGetTexObjMinFilt(pObj); + mMagFilt = GXGetTexObjMagFilt(pObj); + // why? + dataPtr = (char *)GXGetTexObjData(pObj) - 0x80000000; + mpBuffer = nullptr; +} + +CpuTexture::~CpuTexture() { + if ((mFlags & NEEDS_BUFFER_FREE) != 0) { + delete[] mpBuffer; + } +} + +void CpuTexture::configure() { + mFlags = CONFIGURED; +} + +void CpuTexture::setBuffer(void *buf) { + if (buf != nullptr) { + dataPtr = buf; + } + mFlags &= ~HAS_HEADER; +} + +void CpuTexture::load(GXTexMapID id) const { + GXTexObj obj; + getTexObj(&obj); + GXLoadTexObj(&obj, id); +} + +void CpuTexture::getTexObj(GXTexObj *pObj) const { + GXInitTexObj(pObj, dataPtr, mWidth, mHeight, getFormat(), (GXTexWrapMode)mWrapS, (GXTexWrapMode)mWrapT, false); + GXInitTexObjLOD(pObj, (GXTexFilter)mMinFilt, (GXTexFilter)mMagFilt, 0.0f, 0.0f, 0.0f, false, false, GX_ANISO_1); +} + +void CpuTexture::flush() const { + u32 size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + DCFlushRange(dataPtr, size); +} + +void CpuTexture::buildHeader() const { + Header *pHdr = getHeader(); + + pHdr->mTexFormat = mTexFormat; + pHdr->BYTE_0x1 = 1; + pHdr->mWidth = mWidth; + pHdr->mHeight = mHeight; + pHdr->mWrapS = mWrapS; + pHdr->mWrapT = mWrapT; + pHdr->BYTE_0x8 = 0; + pHdr->BYTE_0x9 = 0; + pHdr->SHORT_0xA = 0; + pHdr->WORD_0xC = 0; + pHdr->BYTE_0xD = 0; + pHdr->BYTE_0xE = 0; + pHdr->BYTE_0xF = 0; + pHdr->BYTE_0x10 = 0; + pHdr->mMinFilt = mMinFilt; + pHdr->mMagFilt = mMagFilt; + pHdr->BYTE_0x13 = 0; + pHdr->BYTE_0x14 = 0; + pHdr->BYTE_0x15 = 1; + pHdr->SHORT_0x16 = 0; + pHdr->WORD_0x18 = 32; +} + +void CpuTexture::alloc(Heap *pHeap) { + Heap *heap = pHeap == nullptr ? Heap::getCurrentHeap() : pHeap; + u32 size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + mpBuffer = new (heap, 0x20) char[size]; + setBuffer(mpBuffer); + mFlags |= NEEDS_BUFFER_FREE; +} + +void CpuTexture::allocWithHeaderDebug(Heap *pHeap) { + Heap *heap = pHeap == nullptr ? Heap::getCurrentHeap() : pHeap; + u32 size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + mpBuffer = new (heap, 0x20) char[size + 0x20]; + char *actualBuf = mpBuffer + 0x20; + setBuffer(mpBuffer + 0x20); + if (actualBuf != nullptr) { + mFlags |= HAS_HEADER; + } + mFlags |= NEEDS_BUFFER_FREE; + buildHeader(); +} + +void CpuTexture::allocate(Heap *pHeap) { + alloc(pHeap); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathBase.cpp b/src/egg/gfx/eggDrawPathBase.cpp index e59be480..de88310e 100644 --- a/src/egg/gfx/eggDrawPathBase.cpp +++ b/src/egg/gfx/eggDrawPathBase.cpp @@ -1,3 +1,44 @@ #include "egg/gfx/eggDrawPathBase.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggIScnProc.h" +#include "nw4r/g3d/g3d_scnobj.h" +#include "nw4r/g3d/g3d_scnproc.h" + +namespace EGG { + +DrawPathBase::DrawPathBase() {} + +void DrawPathBase::createScnProc(MEMAllocator *allocator) { + IScnProc::createScnProc(getNumStep(), allocator); + for (u16 i = 0; i < getNumStep(); i++) { + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_UPDATEFRAME, true); + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_WORLD, true); + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_MAT, true); + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_VTX, true); + getProc(i)->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_VIEW, true); + } + nw4r::g3d::ScnProc *p = getProc(0); + p->SetScnObjOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_VIEW, false); + p->EnableScnObjCallbackExecOp(nw4r::g3d::ScnObj::EXECOP_CALC_VIEW); + p->EnableScnObjCallbackTiming(nw4r::g3d::ScnObj::CALLBACK_TIMING_A); + p->DisableScnObjCallbackTiming(nw4r::g3d::ScnObj::CALLBACK_TIMING_B); + p->DisableScnObjCallbackTiming(nw4r::g3d::ScnObj::CALLBACK_TIMING_C); + p->SetCallback(this); +} + +void DrawPathBase::ExecCallback_CALC_VIEW( + nw4r::g3d::ScnObj::Timing timing, nw4r::g3d::ScnObj *pObj, u32 param, void *pInfo +) { + if (mFlag & 1) { + internalResetForDraw(); + } +} + +void DrawPathBase::scnProcDraw(u16) { + if (mFlag & 1) { + internalDraw(); + } +} + +} // namespace EGG diff --git a/src/egg/gfx/eggGlobalDrawState.cpp b/src/egg/gfx/eggGlobalDrawState.cpp index 12a37a32..bb1f3df3 100644 --- a/src/egg/gfx/eggGlobalDrawState.cpp +++ b/src/egg/gfx/eggGlobalDrawState.cpp @@ -24,9 +24,9 @@ void GlobalDrawState::beginDrawView(u16 cameraId, const nw4r::math::MTX34 &mtx, } void GlobalDrawState::setDrawSettingGX(bool b1, bool b2) { - StateGX::GXSetColorUpdate_(sDrawFlag & 1); - StateGX::GXSetAlphaUpdate_(sDrawFlag & 2); - StateGX::GXSetDither_(sDrawFlag & 4); + StateGX::GXSetColorUpdate_((sDrawFlag & 1) != 0); + StateGX::GXSetAlphaUpdate_((sDrawFlag & 2) != 0); + StateGX::GXSetDither_((sDrawFlag & 4) != 0); StateGX::GXSetDstAlpha_(false, 0); if (b2 && spScreen != nullptr) { spScreen->SetProjectionGX(); diff --git a/src/egg/gfx/eggIScnProc.cpp b/src/egg/gfx/eggIScnProc.cpp index e293cc91..25e3dafa 100644 --- a/src/egg/gfx/eggIScnProc.cpp +++ b/src/egg/gfx/eggIScnProc.cpp @@ -82,7 +82,7 @@ void IScnProc::drawProcFunc(nw4r::g3d::ScnProc *pScnProc, bool b) { void IScnProc::drawProcFuncNoGlobalState(nw4r::g3d::ScnProc *pScnProc, bool b) { ProcData *dat = static_cast(pScnProc->GetUserData()); - dat->mpThis->doDraw(dat->mIndex); + dat->mpThis->scnProcDraw(dat->mIndex); } } // namespace EGG diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp index d1110185..4dd44128 100644 --- a/src/egg/gfx/eggPostEffectBase.cpp +++ b/src/egg/gfx/eggPostEffectBase.cpp @@ -1,3 +1,25 @@ #include "egg/gfx/eggPostEffectBase.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +PostEffectBase::PostEffectBase() { + field_0x00 = 0; + mpCapTexture = nullptr; + mTexMapId = GX_TEXMAP0; + mpCapTexture2 = nullptr; + mTexMapId2 = GX_TEXMAP0; + mOffsetX = 0.0f; + mOffsetY = 0.0f; + mScaleX = 1.0f; + mScaleY = 1.0f; + field_0x24 = 0.0f; +} + +void PostEffectBase::loadTextureInternal() { + mpCapTexture; +} + +} // namespace EGG diff --git a/src/toBeSorted/d_d3d.cpp b/src/toBeSorted/d_d3d.cpp index 9ed56f95..0b885de7 100644 --- a/src/toBeSorted/d_d3d.cpp +++ b/src/toBeSorted/d_d3d.cpp @@ -327,7 +327,7 @@ void setRoomTevColors(nw4r::g3d::ResMdl mdl, int b1, bool bUnk) { void UnkWithWater::calc(EGG::CpuTexture *tex) { GXTexObj obj; if (tex != nullptr) { - tex->GetTexObj(&obj); + tex->getTexObj(&obj); } for (NodeList::Iterator it = mList.GetBeginIter(); it != mList.GetEndIter(); ++it) { From 03e3fc5cfa63076033005cb9079e37d21103f473 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 15 Mar 2025 23:20:09 +0100 Subject: [PATCH 03/62] More --- config/SOUE01/splits.txt | 5 +-- config/SOUE01/symbols.txt | 12 +++---- configure.py | 2 +- include/egg/gfx/eggDrawPathDOF.h | 28 ++++++++++++++++- include/egg/gfx/eggStateGX.h | 54 +++++++++++++++++++++++++++++--- include/egg/prim/eggBinary.h | 2 ++ src/egg/gfx/eggCapTexture.cpp | 8 ++--- src/egg/gfx/eggDrawPathDOF.cpp | 18 ++++++++++- 8 files changed, 108 insertions(+), 21 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 02ccf1cf..db75cf74 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2178,8 +2178,8 @@ egg/gfx/eggUnk1.cpp: .text start:0x8049CFF0 end:0x8049D7C0 egg/gfx/eggCapTexture.cpp: - .text start:0x8049D7C0 end:0x8049D9D0 - .rodata start:0x804FBA30 end:0x804FBA60 + .text start:0x8049D7C0 end:0x8049D9C4 + .rodata start:0x804FBA30 end:0x804FBA48 .data start:0x8056ED70 end:0x8056ED80 .sdata2 start:0x8057F410 end:0x8057F418 .sbss2 start:0x8057FFC0 end:0x8057FFC8 @@ -2201,6 +2201,7 @@ egg/gfx/eggDrawPathUnk1.cpp: egg/gfx/eggDrawPathDOF.cpp: .text start:0x804A29C0 end:0x804A4BE8 + .data start:0x8056EF28 end:0x8056EFA0 egg/gfx/eggDrawPathUnk2.cpp: .text start:0x804A4BF0 end:0x804A54E8 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index d743d8d6..c032f17e 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26779,11 +26779,11 @@ resetPE__Q23EGG7StateGXFv = .text:0x804B4EF0; // type:function size:0xB0 resetGXCache__Q23EGG7StateGXFv = .text:0x804B4FA0; // type:function size:0x40 EGG__StateGX__GXSetPixelFmt_ = .text:0x804B4FE0; // type:function size:0xAC invalidateTexAllGX__Q23EGG7StateGXFv = .text:0x804B5090; // type:function size:0x4 -GXSetColorUpdate___Q23EGG7StateGXFUc = .text:0x804B50A0; // type:function size:0x4C -GXSetAlphaUpdate___Q23EGG7StateGXFUc = .text:0x804B50F0; // type:function size:0x4C -GXSetDither___Q23EGG7StateGXFUc = .text:0x804B5140; // type:function size:0x4C +GXSetColorUpdate___Q23EGG7StateGXFb = .text:0x804B50A0; // type:function size:0x4C +GXSetAlphaUpdate___Q23EGG7StateGXFb = .text:0x804B50F0; // type:function size:0x4C +GXSetDither___Q23EGG7StateGXFb = .text:0x804B5140; // type:function size:0x4C GXCopyTex__Q23EGG7StateGXFPvb = .text:0x804B5190; // type:function size:0x8 -GXSetDstAlpha___Q23EGG7StateGXFUcUc = .text:0x804B51A0; // type:function size:0x4C +GXSetDstAlpha___Q23EGG7StateGXFbUc = .text:0x804B51A0; // type:function size:0x4C FUN_804b51f0 = .text:0x804B51F0; // type:function size:0x108 FUN_804b5300 = .text:0x804B5300; // type:function size:0x2C GXSetProjectionv___Q23EGG7StateGXFPCf = .text:0x804B5330; // type:function size:0x2C @@ -29159,7 +29159,7 @@ gRMO_Ntsc_640x456Prog_4x3__22@unnamed@eggVideo_cpp@ = .rodata:0x804FB980; // typ gRMO_Ntsc_640x456IntDf_4x3__22@unnamed@eggVideo_cpp@ = .rodata:0x804FB9BC; // type:object size:0x3C scope:local 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:0x30 +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 @@ -37362,7 +37362,7 @@ jumptable_8056EDE0 = .data:0x8056EDE0; // type:object size:0x38 scope:local jumptable_8056EE18 = .data:0x8056EE18; // type:object size:0x48 scope:local __vt__Q23EGG12DrawPathBase = .data:0x8056EE60; // type:object size:0x50 lbl_8056EEB0 = .data:0x8056EEB0; // type:object size:0x78 -lbl_8056EF28 = .data:0x8056EF28; // type:object size:0x78 +__vt__Q23EGG11DrawPathDOF = .data:0x8056EF28; // type:object size:0x78 lbl_8056EFA0 = .data:0x8056EFA0; // type:object size:0x50 __vt__Q23EGG3Fog = .data:0x8056EFF0; // type:object size:0x20 __vt__Q23EGG10FogManager = .data:0x8056F010; // type:object size:0x20 diff --git a/configure.py b/configure.py index 69f286ad..e6d9ba62 100644 --- a/configure.py +++ b/configure.py @@ -869,7 +869,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggPalette.cpp"), Object(NonMatching, "egg/gfx/eggTexture.cpp"), Object(NonMatching, "egg/gfx/eggUnk1.cpp"), # Unknown - Object(NonMatching, "egg/gfx/eggCapTexture.cpp"), + Object(Matching, "egg/gfx/eggCapTexture.cpp"), Object(NonMatching, "egg/gfx/eggCpuTexture.cpp"), Object(NonMatching, "egg/gfx/eggDrawGX.cpp"), Object(Matching, "egg/gfx/eggDrawPathBase.cpp"), diff --git a/include/egg/gfx/eggDrawPathDOF.h b/include/egg/gfx/eggDrawPathDOF.h index 054464d1..84a15f6a 100644 --- a/include/egg/gfx/eggDrawPathDOF.h +++ b/include/egg/gfx/eggDrawPathDOF.h @@ -1,6 +1,32 @@ #ifndef EGG_DRAW_PATH_DOF_H #define EGG_DRAW_PATH_DOF_H -namespace EGG {} // namespace EGG +#include "egg/prim/eggBinary.h" +#include "egg/gfx/eggDrawPathBase.h" + +namespace EGG { + +class DrawPathDOF : public DrawPathBase, public IBinary { +public: + class BinData { + // TODO + }; + DrawPathDOF(); + virtual ~DrawPathDOF(); + + virtual u16 getNumStep() { + return 3; + } + virtual void internalResetForDraw() override; + virtual void internalDraw() override; + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; +private: + void *IHaveMembers; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggStateGX.h b/include/egg/gfx/eggStateGX.h index 1d15ad01..321586ba 100644 --- a/include/egg/gfx/eggStateGX.h +++ b/include/egg/gfx/eggStateGX.h @@ -8,6 +8,52 @@ namespace EGG { class StateGX { public: + + struct ScopedColor + { + ScopedColor(bool x) + { + old = GXSetColorUpdate_(x); + } + + ~ScopedColor() + { + GXSetColorUpdate_(old); + } + + bool old; + }; + + struct ScopedAlpha + { + ScopedAlpha(bool x) + { + old = GXSetAlphaUpdate_(x); + } + + ~ScopedAlpha() + { + GXSetAlphaUpdate_(old); + } + + bool old; + }; + + struct ScopedDither + { + ScopedDither(bool x) + { + old = GXSetDither_(x); + } + + ~ScopedDither() + { + GXSetDither_(old); + } + + bool old; + }; + static void initialize(u16, u16, GXColor, GXPixelFmt); static void frameInit(); static void textureInit(); // Guess for 804b4810 @@ -27,10 +73,10 @@ public: static void invalidateTexAllGX(); - static GXBool GXSetColorUpdate_(GXBool); - static GXBool GXSetAlphaUpdate_(GXBool); - static GXBool GXSetDither_(GXBool); - static GXBool GXSetDstAlpha_(GXBool, u8); + static bool GXSetColorUpdate_(bool); + static bool GXSetAlphaUpdate_(bool); + static bool GXSetDither_(bool); + static bool GXSetDstAlpha_(bool, u8); static bool GXSetColorUpdate(bool); static bool GXSetAlphaUpdate(bool); diff --git a/include/egg/prim/eggBinary.h b/include/egg/prim/eggBinary.h index 990bd03c..f962a254 100644 --- a/include/egg/prim/eggBinary.h +++ b/include/egg/prim/eggBinary.h @@ -42,6 +42,8 @@ protected: /** Load the object from binary, interpolating between values */ virtual void SetBinaryInner(const Bin &, const Bin &, f32) = 0; + virtual ~IBinary() {} + /** Get a 4-bytes long ID string corresponding to this type */ static const char *GetBinaryType(); /** Get the current version of this type */ diff --git a/src/egg/gfx/eggCapTexture.cpp b/src/egg/gfx/eggCapTexture.cpp index 166275ae..9aee5996 100644 --- a/src/egg/gfx/eggCapTexture.cpp +++ b/src/egg/gfx/eggCapTexture.cpp @@ -35,9 +35,8 @@ void CapTexture::capture(u16 x, u16 y, bool upscale, int format) { 0, copyArg2, (mCapFlags & 8) ? true : false, (mCapFlags & 8) ? mCopyFilterArg.values : defaultFilter.values ); - // Regswap, grr - GXBool prevColorUpdate = StateGX::GXSetColorUpdate_((mCapFlags & 1) != 0); - GXBool prevAlphaUpdate = StateGX::GXSetAlphaUpdate_((mCapFlags & 2) != 0); + StateGX::ScopedColor colorUpdate((mCapFlags & 1) != 0); + StateGX::ScopedAlpha alphaUpdate((mCapFlags & 2) != 0); GXSetZMode(true, GX_ALWAYS, (mCapFlags & 4) != 0); GXSetCopyClear(mClearColor, field_0x20); GXSetCopyClamp(3); @@ -51,9 +50,6 @@ void CapTexture::capture(u16 x, u16 y, bool upscale, int format) { if ((mCapFlags & 0x20) != 0) { StateGX::invalidateTexAllGX(); } - - StateGX::GXSetAlphaUpdate_(prevAlphaUpdate); - StateGX::GXSetColorUpdate_(prevColorUpdate); } } // namespace EGG diff --git a/src/egg/gfx/eggDrawPathDOF.cpp b/src/egg/gfx/eggDrawPathDOF.cpp index 8f611cde..588f02ba 100644 --- a/src/egg/gfx/eggDrawPathDOF.cpp +++ b/src/egg/gfx/eggDrawPathDOF.cpp @@ -1,3 +1,19 @@ #include "egg/gfx/eggDrawPathDOF.h" -namespace EGG {} // namespace EGG +namespace EGG { + +DrawPathDOF::DrawPathDOF() {} + +DrawPathDOF::~DrawPathDOF() {} + +void DrawPathDOF::internalDraw() {} + +void DrawPathDOF::internalResetForDraw() {} + +void DrawPathDOF::SetBinaryInner(const Bin &bin) {} + +void DrawPathDOF::GetBinaryInner(Bin *pBin) const {} + +void DrawPathDOF::SetBinaryInner(const Bin &, const Bin &, f32) {} + +} // namespace EGG From 861a78a44674c7d1a0851f71186ec24ca5f74449 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 16 Mar 2025 01:39:17 +0100 Subject: [PATCH 04/62] PostEffectBase almost --- config/SOUE01/splits.txt | 4 + config/SOUE01/symbols.txt | 44 ++++----- include/egg/gfx/eggDrawGX.h | 49 +++++++++- include/egg/gfx/eggDrawPathDOF.h | 5 +- include/egg/gfx/eggFrustum.h | 34 +++++++ include/egg/gfx/eggPostEffectBase.h | 20 +++- include/egg/gfx/eggScreen.h | 1 + src/egg/gfx/eggPostEffectBase.cpp | 140 +++++++++++++++++++++++++++- 8 files changed, 266 insertions(+), 31 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index db75cf74..ff5d9aef 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2257,6 +2257,10 @@ egg/gfx/eggModelEx.cpp: egg/gfx/eggPostEffectBase.cpp: .text start:0x804AEC20 end:0x804AF4B4 + .data start:0x8056F120 end:0x8056F170 + .sbss start:0x80576860 end:0x80576870 + .sdata2 start:0x8057F720 end:0x8057F750 + .bss start:0x80674EF0 end:0x80674F00 egg/gfx/eggPostEffectBlur.cpp: .text start:0x804AF4C0 end:0x804AFC04 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index c032f17e..cdb9304c 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -678,7 +678,7 @@ 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 -fn_8001D590 = .text:0x8001D590; // 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 fn_8001D640 = .text:0x8001D640; // type:function size:0xE4 @@ -9792,7 +9792,7 @@ fn_80174130 = .text:0x80174130; // type:function size:0x1D8 fn_80174310 = .text:0x80174310; // type:function size:0x5F0 internalResetForDraw__Q23EGG12DrawPathBaseFv = .text:0x80174900; // type:function size:0x4 fn_80174910 = .text:0x80174910; // type:function size:0x8 -fn_80174920 = .text:0x80174920; // type:function size:0x4 +setMaterialInternal__Q23EGG14PostEffectBaseFv = .text:0x80174920; // type:function size:0x4 fn_80174930 = .text:0x80174930; // type:function size:0x8 fn_80174940 = .text:0x80174940; // type:function size:0x14 fn_80174960 = .text:0x80174960; // type:function size:0x8 @@ -10655,7 +10655,7 @@ fn_8019C260 = .text:0x8019C260; // type:function size:0x4 fn_8019C270 = .text:0x8019C270; // type:function size:0x4 fn_8019C280 = .text:0x8019C280; // type:function size:0x4 fn_8019C290 = .text:0x8019C290; // type:function size:0x8 -fn_8019C2A0 = .text:0x8019C2A0; // type:function size:0x8 +getNumStep__Q23EGG11DrawPathDOFCFv = .text:0x8019C2A0; // type:function size:0x8 build__27sFStateFct_c<11dStageMgr_c>FRC12sStateIDIf_c = .text:0x8019C2B0; // type:function size:0x60 dispose__27sFStateFct_c<11dStageMgr_c>FRP10sStateIf_c = .text:0x8019C310; // type:function size:0xC initialize__24sFState_c<11dStageMgr_c>Fv = .text:0x8019C320; // type:function size:0x1C @@ -10674,7 +10674,7 @@ hasReachedEnd__22sFPhase<11dStageMgr_c>CFv = .text:0x8019C430; // type:function fn_8019C460 = .text:0x8019C460; // type:function size:0x10 fn_8019C470 = .text:0x8019C470; // type:function size:0x10 SetBinary__Q23EGG19IBinaryFPCv = .text:0x8019C480; // type:function size:0x10 -fn_8019C490 = .text:0x8019C490; // type:function size:0x8 +GetBinarySize__Q23EGG28IBinaryCFv = .text:0x8019C490; // type:function size:0x8 fn_8019C4A0 = .text:0x8019C4A0; // type:function size:0x10 fn_8019C4B0 = .text:0x8019C4B0; // type:function size:0x8 fn_8019C4C0 = .text:0x8019C4C0; // type:function size:0x10 @@ -10686,9 +10686,9 @@ __dt__26sFStateID_c<11dStageMgr_c>Fv = .text:0x8019CDE0; // type:function size:0 isSameName__26sFStateID_c<11dStageMgr_c>CFPCc = .text:0x8019CE40; // type:function size:0x88 fn_8019CED0 = .text:0x8019CED0; // type:function size:0x8 fn_8019CEE0 = .text:0x8019CEE0; // type:function size:0x8 -fn_8019CEF0 = .text:0x8019CEF0; // type:function size:0x8 -fn_8019CF00 = .text:0x8019CF00; // type:function size:0x8 -fn_8019CF10 = .text:0x8019CF10; // type:function size:0x8 +@24@SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3Bin = .text:0x8019CEF0; // type:function size:0x8 +@24@SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3BinRCQ33EGG28IBinary3Binf = .text:0x8019CF00; // type:function size:0x8 +@24@GetBinaryInner__Q23EGG11DrawPathDOFCFPQ33EGG28IBinary3Bin = .text:0x8019CF10; // type:function size:0x8 fn_8019CF20 = .text:0x8019CF20; // type:function size:0x8 fn_8019CF30 = .text:0x8019CF30; // type:function size:0x8 fn_8019CF40 = .text:0x8019CF40; // type:function size:0x8 @@ -26498,22 +26498,22 @@ FUN_804a2960 = .text:0x804A2960; // type:function size:0x28 fn_804A2990 = .text:0x804A2990; // type:function size:0x8 fn_804A29A0 = .text:0x804A29A0; // type:function size:0x8 fn_804A29B0 = .text:0x804A29B0; // type:function size:0x8 -EGG__DrawPathDOF____ct = .text:0x804A29C0; // type:function size:0x164 -EGG__DrawPathDOF____dt = .text:0x804A2B30; // type:function size:0x104 +__ct__Q23EGG11DrawPathDOFFv = .text:0x804A29C0; // type:function size:0x164 +__dt__Q23EGG11DrawPathDOFFv = .text:0x804A2B30; // type:function size:0x104 fn_804A2C40 = .text:0x804A2C40; // type:function size:0x40 fn_804A2C80 = .text:0x804A2C80; // type:function size:0x9C -FUN_804a2d20 = .text:0x804A2D20; // type:function size:0x324 -FUN_804a3050 = .text:0x804A3050; // type:function size:0xCC +internalResetForDraw__Q23EGG11DrawPathDOFFv = .text:0x804A2D20; // type:function size:0x324 +internalDraw__Q23EGG11DrawPathDOFFv = .text:0x804A3050; // type:function size:0xCC FUN_804a3120 = .text:0x804A3120; // type:function size:0x9A4 EGG__DrawPathDOF__internalDraw = .text:0x804A3AD0; // type:function size:0x648 FUN_804a4120 = .text:0x804A4120; // type:function size:0x224 FUN_804a4350 = .text:0x804A4350; // type:function size:0xDC -EGG__DrawPathDOF__SetBinaryInner = .text:0x804A4430; // type:function size:0x238 -EGG__DrawPathDOF__GetBinaryInner = .text:0x804A4670; // type:function size:0xD8 -EGG__DrawPathDOF__SetBinaryInner2 = .text:0x804A4750; // type:function size:0x464 -EGG__DrawPathDOF___8_dt = .text:0x804A4BC0; // type:function size:0x8 -EGG__DrawPathDOF___20_dt = .text:0x804A4BD0; // type:function size:0x8 -EGG__DrawPathDOF___24_dt = .text:0x804A4BE0; // type:function size:0x8 +SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3Bin = .text:0x804A4430; // type:function size:0x238 +GetBinaryInner__Q23EGG11DrawPathDOFCFPQ33EGG28IBinary3Bin = .text:0x804A4670; // type:function size:0xD8 +SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3BinRCQ33EGG28IBinary3Binf = .text:0x804A4750; // type:function size:0x464 +@8@__dt__Q23EGG11DrawPathDOFFv = .text:0x804A4BC0; // type:function size:0x8 +@20@__dt__Q23EGG11DrawPathDOFFv = .text:0x804A4BD0; // type:function size:0x8 +@24@__dt__Q23EGG11DrawPathDOFFv = .text:0x804A4BE0; // type:function size:0x8 EGG__DrawPathShadowVolume____ct = .text:0x804A4BF0; // type:function size:0x7C FUN_804a4c70 = .text:0x804A4C70; // type:function size:0x3C EGG__DrawPathShadowVolume__internalDraw = .text:0x804A4CB0; // type:function size:0x7B4 @@ -26690,7 +26690,7 @@ EGG__ModelEx__getResMdl = .text:0x804AEB40; // type:function size:0x48 EGG__ModelEx__getResShp = .text:0x804AEB90; // type:function size:0x90 __ct__Q23EGG14PostEffectBaseFv = .text:0x804AEC20; // type:function size:0x5C draw__Q23EGG14PostEffectBaseFff = .text:0x804AEC80; // type:function size:0x94 -setMaterialInternal__Q23EGG14PostEffectBaseFv = .text:0x804AED20; // type:function size:0x60 +fn_804AED20__Q23EGG14PostEffectBaseFv = .text:0x804AED20; // type:function size:0x60 setVtxState__Q23EGG14PostEffectBaseFv = .text:0x804AED80; // type:function size:0x8 drawScreenInternal__Q23EGG14PostEffectBaseFffff = .text:0x804AED90; // type:function size:0x8C loadTextureInternal__Q23EGG14PostEffectBaseFv = .text:0x804AEE20; // type:function size:0x48 @@ -37375,7 +37375,7 @@ EGG__LightTexture__vtable = .data:0x8056F0B8; // type:object size:0x38 EGG__LightTextureManager__vtable = .data:0x8056F0F0; // type:object size:0x20 lbl_8056F110 = .data:0x8056F110; // type:object size:0x10 jumptable_8056F120 = .data:0x8056F120; // type:object size:0x30 scope:local -lbl_8056F150 = .data:0x8056F150; // type:object size:0x20 +__vt__Q23EGG14PostEffectBase = .data:0x8056F150; // type:object size:0x1C lbl_8056F170 = .data:0x8056F170; // type:object size:0x20 lbl_8056F190 = .data:0x8056F190; // type:object size:0x20 lbl_8056F1B0 = .data:0x8056F1B0; // type:object size:0x20 @@ -41171,7 +41171,7 @@ lbl_80576858 = .sbss:0x80576858; // type:object size:0x4 data:4byte lbl_8057685C = .sbss:0x8057685C; // type:object size:0x1 data:byte lbl_80576860 = .sbss:0x80576860; // type:object size:0x1 data:byte lbl_80576861 = .sbss:0x80576861; // type:object size:0x7 data:byte -lbl_80576868 = .sbss:0x80576868; // type:object size:0x4 data:float +lbl_80576868 = .sbss:0x80576868; // type:object size:0x8 data:float sTVMode__Q23EGG6Screen = .sbss:0x80576870; // type:object size:0x4 data:4byte lbl_80576874 = .sbss:0x80576874; // type:object size:0x4 data:4byte lbl_80576878 = .sbss:0x80576878; // type:object size:0x4 data:4byte @@ -49797,13 +49797,13 @@ ex__Q23EGG8Vector3f = .bss:0x80674C3C; // type:object size:0xC data:float 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 -lbl_80674D68 = .bss:0x80674D68; // type:object size:0x90 +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 sMtx__Q23EGG15GlobalDrawState = .bss:0x80674E48; // type:object size:0x30 CPU_TEX_ARR = .bss:0x80674E78; // type:object size:0x48 data:4byte lbl_80674EC0 = .bss:0x80674EC0; // type:object size:0x30 data:float -lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0x10 data:float +lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0xC data:float lbl_80674F00 = .bss:0x80674F00; // type:object size:0x88 data:4byte sScreen__Q23EGG16ScreenEffectBase = .bss:0x80674F88; // type:object size:0x88 lbl_80675010 = .bss:0x80675010; // type:object size:0x30 diff --git a/include/egg/gfx/eggDrawGX.h b/include/egg/gfx/eggDrawGX.h index 1fc4f6b8..6fe69326 100644 --- a/include/egg/gfx/eggDrawGX.h +++ b/include/egg/gfx/eggDrawGX.h @@ -5,13 +5,19 @@ #include "egg/core/eggHeap.h" #include "egg/gfx/eggTexture.h" #include "egg/math/eggMatrix.h" -#include "rvl/GX.h" // IWYU pragma: export +#include "rvl/GX.h" // IWYU pragma: export namespace EGG { class DrawGX { public: + // made up + struct DLData { + void *mpList; + u32 mLen; + }; + enum DL { DL_0, DL_1, @@ -35,16 +41,55 @@ public: DL_MAX }; + enum VtxType { + VTX_TYPE_0, + VTX_TYPE_1, + VTX_TYPE_2, + VTX_TYPE_3, + VTX_TYPE_4, + VTX_TYPE_5, + VTX_TYPE_6, + VTX_TYPE_7, + VTX_TYPE_8, + VTX_TYPE_9, + VTX_TYPE_10, + VTX_TYPE_11, + VTX_TYPE_12, + VTX_TYPE_13 + }; + + enum Blend { + BLEND_0, + BLEND_1, + BLEND_2, + BLEND_3, + BLEND_4, + BLEND_5, + BLEND_6, + BLEND_7, + BLEND_8, + BLEND_9, + BLEND_10, + BLEND_11, + BLEND_12, + BLEND_13, + BLEND_14, + + BLEND_MAX + }; + static void Initialize(Heap *); static GXTexMapID GetTexMapDefault(); static void LoadTexture(const EGG::ResTIMG *, GXTexMapID); static void BeginDrawScreen(bool, bool, bool); static void DrawDL(enum DL, const nw4r::math::MTX34 &, GXColor); + static void SetVtxState(enum VtxType); + static void SetBlendMode(enum Blend); // TODO MORE - /* static ?? s_DL */ + static DLData s_DL[DL_MAX]; static Matrix34f s_cameraMtx; diff --git a/include/egg/gfx/eggDrawPathDOF.h b/include/egg/gfx/eggDrawPathDOF.h index 84a15f6a..3e523d45 100644 --- a/include/egg/gfx/eggDrawPathDOF.h +++ b/include/egg/gfx/eggDrawPathDOF.h @@ -1,8 +1,8 @@ #ifndef EGG_DRAW_PATH_DOF_H #define EGG_DRAW_PATH_DOF_H -#include "egg/prim/eggBinary.h" #include "egg/gfx/eggDrawPathBase.h" +#include "egg/prim/eggBinary.h" namespace EGG { @@ -14,7 +14,7 @@ public: DrawPathDOF(); virtual ~DrawPathDOF(); - virtual u16 getNumStep() { + virtual u16 getNumStep() const override { return 3; } virtual void internalResetForDraw() override; @@ -23,6 +23,7 @@ public: virtual void SetBinaryInner(const Bin &) override; virtual void GetBinaryInner(Bin *) const override; virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + private: void *IHaveMembers; }; diff --git a/include/egg/gfx/eggFrustum.h b/include/egg/gfx/eggFrustum.h index 568b6d73..01c93063 100644 --- a/include/egg/gfx/eggFrustum.h +++ b/include/egg/gfx/eggFrustum.h @@ -10,12 +10,19 @@ namespace EGG { class Frustum { public: enum CanvasMode { + CANVAS_0, + CANVAS_1, }; enum ProjectionType { PROJ_ORTHO, PROJ_PERSP }; + enum Flag { + FLAG_DIRTY = (1 << 0), + FLAG_0x40 = 0x40, + }; + private: /* 0x00 */ ProjectionType mProjType; /* 0x04 */ CanvasMode mCanvasMode; @@ -41,6 +48,33 @@ public: mProjType = type; } + void SetDirty(bool dirty) const { + if (dirty) { + mFlags |= FLAG_DIRTY; + } else { + mFlags &= ~FLAG_DIRTY; + } + } + + void SetFlag(Flag f) const { + mFlags |= f; + } + + CanvasMode GetCanvasMode() const { + return mCanvasMode; + } + void SetCanvasMode(CanvasMode mode) { + if (mCanvasMode != mode) { + SetDirty(true); + mCanvasMode = mode; + } + } + + void SetNearFar(f32 near, f32 far) { + mNearZ = near; + mFarZ = far; + } + void ResetOrthographic(f32, f32, f32, f32, f32, f32); void SetScale(const nw4r::math::VEC3 &scale) { diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index 2133c646..d35a1efb 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -24,11 +24,23 @@ protected: PostEffectBase(); virtual ~PostEffectBase() {} // at 0x8 + void fn_804AED20(); + + void setVtxState(); + void setMatColorChannel(); + 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); + void getBaseTexMtx(nw4r::math::MTX34 *mtx) const; + static void setProjection(const EGG::Screen &screen); + protected: - virtual void draw(f32, f32); // at 0xC - virtual void setMaterialInternal(); // at 0x10 - virtual void loadTextureInternal(); // at 0x14 - virtual void drawScreenInternal(f32, f32, f32, f32); // at 0x18 + virtual void draw(f32 width, f32 height); // at 0xC + virtual void setMaterialInternal() {} // at 0x10 + virtual void loadTextureInternal(); // at 0x14 + virtual void drawScreenInternal(f32 offsetX, f32 offsetY, f32 width, f32 height); // at 0x18 }; } // namespace EGG diff --git a/include/egg/gfx/eggScreen.h b/include/egg/gfx/eggScreen.h index 12a5fa1a..699df321 100644 --- a/include/egg/gfx/eggScreen.h +++ b/include/egg/gfx/eggScreen.h @@ -10,6 +10,7 @@ namespace EGG { class Screen : public Frustum { public: Screen(); + Screen(const Screen &other); Screen(f32, f32, f32, f32, Screen *, CanvasMode); virtual ~Screen() {} diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp index 4dd44128..8f0e3368 100644 --- a/src/egg/gfx/eggPostEffectBase.cpp +++ b/src/egg/gfx/eggPostEffectBase.cpp @@ -1,7 +1,18 @@ #include "egg/gfx/eggPostEffectBase.h" #include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggScreen.h" +#include "egg/math/eggVector.h" +#include "math.h" +#include "nw4r/math/math_triangular.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXDisplayList.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTransform.h" #include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" namespace EGG { @@ -18,8 +29,135 @@ PostEffectBase::PostEffectBase() { field_0x24 = 0.0f; } +void PostEffectBase::draw(f32 width, f32 height) { + setMaterialInternal(); + setVtxState(); + drawScreenInternal(mOffsetX, mOffsetY, mScaleX * width, mScaleY * height); +} + +void PostEffectBase::fn_804AED20() { + draw(mpCapTexture->getWidth(), mpCapTexture->getHeight()); +} + +void PostEffectBase::setVtxState() { + DrawGX::SetVtxState(DrawGX::VTX_TYPE_11); +} + +void PostEffectBase::drawScreenInternal(f32 offsetX, f32 offsetY, f32 width, f32 height) { + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, width, height, 1.0f); + mtx._03 = offsetX; + mtx._13 = offsetY; + mtx._23 = 0.0f; + GXLoadPosMtxImm(mtx, 0); + GXCallDisplayList(DrawGX::s_DL[DrawGX::DL_16].mpList, DrawGX::s_DL[DrawGX::DL_16].mLen); +} + void PostEffectBase::loadTextureInternal() { - mpCapTexture; + mpCapTexture->load(mTexMapId); + if (mpCapTexture2 != nullptr) { + mpCapTexture2->load(mTexMapId2); + } +} + +void PostEffectBase::setMatColorChannel() { + GXSetNumChans(0); + GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_SIGN, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_SIGN, GX_AF_NONE); + GXSetCullMode(GX_CULL_BACK); +} + +void PostEffectBase::setMatInd() { + GXSetNumIndStages(0); +} + +void PostEffectBase::setMatPE() { + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + GXSetZMode(false, GX_ALWAYS, false); + static const GXColor black = {0, 0, 0, 0xFF}; + GXSetFog(GX_FOG_NONE, black, 0.0, 1.0, 0.0, 1.0); + setBlendModeInternal(); +} + +void PostEffectBase::setBlendModeInternal() { + switch (field_0x00) { + case 0: DrawGX::SetBlendMode(DrawGX::BLEND_14); break; + case 1: DrawGX::SetBlendMode(DrawGX::BLEND_0); break; + case 2: DrawGX::SetBlendMode(DrawGX::BLEND_2); break; + case 3: DrawGX::SetBlendMode(DrawGX::BLEND_4); break; + case 4: GXSetBlendMode(GX_BM_BLEND, GX_BL_DSTCLR, GX_BL_INVDSTCLR, GX_LO_CLEAR); break; + case 5: DrawGX::SetBlendMode(DrawGX::BLEND_5); break; + case 6: GXSetBlendMode(GX_BM_BLEND, GX_BL_INVSRCCLR, GX_BL_INVSRCCLR, GX_LO_CLEAR); break; + case 7: DrawGX::SetBlendMode(DrawGX::BLEND_3); break; + case 8: GXSetBlendMode(GX_BM_BLEND, GX_BL_INVSRCALPHA, GX_BL_ONE, GX_LO_CLEAR); break; + case 9: GXSetBlendMode(GX_BM_SUBTRACT, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); break; + case 10: DrawGX::SetBlendMode(DrawGX::BLEND_7); break; + case 11: GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ZERO, GX_LO_CLEAR); break; + } +} + +void PostEffectBase::fn_804AF040(GXColor &out, const GXColor &c, bool bClamp, f32 amount) { + f32 fs[4]; + fs[0] = c.r * amount; + fs[1] = c.g * amount; + fs[2] = c.b * amount; + fs[3] = c.a * amount; + + if (bClamp) { + out.r = fs[0] < 255.0f ? fs[0] : 255.0f; + out.g = fs[1] < 255.0f ? fs[1] : 255.0f; + out.b = fs[2] < 255.0f ? fs[2] : 255.0f; + out.a = fs[3] < 255.0f ? fs[3] : 255.0f; + } else { + out.r = fs[0]; + out.g = fs[1]; + out.b = fs[2]; + out.a = fs[3]; + } +} + +void PostEffectBase::fn_804AF1B0(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); + out.a = c1.a + amount * (c2.a - c1.a); +} + +void PostEffectBase::getBaseTexMtx(nw4r::math::MTX34 *mtx) const { + f32 sin, cos; + nw4r::math::SinCosRad(&sin, &cos, field_0x24 * M_PI); + f32 zero = 0.0f; + f32 scale = 1.0f; + f32 f8 = zero - 0.5f; + + mtx->_00 = scale * cos; + mtx->_01 = scale * sin; + mtx->_02 = ((f8 * cos) - (sin * (f8 + scale))) + 0.5f; + + mtx->_10 = -scale * sin; + mtx->_11 = scale * cos; + mtx->_12 = ((-f8 * sin) - (cos * (f8 + scale))) + 0.5f; + + mtx->_23 = zero; + mtx->_21 = zero; + mtx->_20 = zero; + mtx->_13 = zero; + mtx->_03 = zero; + mtx->_22 = scale; +} + +void PostEffectBase::setProjection(const Screen &screen) { + static Vector3f sScale(1.0f, 1.0f, 1.0f); + static Vector2f sOffset(0.0f, 0.0f); + + Screen screenCpy(screen); + screenCpy.SetFlag(Screen::FLAG_0x40); + screenCpy.SetCanvasMode(Screen::CANVAS_1); + screenCpy.SetProjectionType(Screen::PROJ_ORTHO); + screenCpy.SetNearFar(0.0f, 1.0f); + screenCpy.SetScale(sScale); + screenCpy.SetOffset(sOffset); + screenCpy.SetProjectionGX(); } } // namespace EGG From f622030c7162b22b7642506e9a82f5120ca3f18f Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 16 Mar 2025 12:42:34 +0100 Subject: [PATCH 05/62] Rough outline for LightTexture --- config/SOUE01/splits.txt | 5 + config/SOUE01/symbols.txt | 20 +-- include/egg/gfx/eggCapTexture.h | 13 ++ include/egg/gfx/eggCpuTexture.h | 14 +- include/egg/gfx/eggLight.h | 21 +-- include/egg/gfx/eggLightTexture.h | 82 ++++++++++- include/egg/gfx/eggLightTextureMgr.h | 27 +++- include/egg/gfx/eggPostEffectBase.h | 2 +- include/egg/prim/eggBinary.h | 2 +- src/egg/gfx/eggLightTexture.cpp | 186 +++++++++++++++++++++++- src/egg/gfx/eggPostEffectBase.cpp | 4 +- src/m/m3d/m3d.cpp | 2 + src/toBeSorted/arc_callback_handler.cpp | 2 +- 13 files changed, 341 insertions(+), 39 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index ff5d9aef..9ed8d492 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2248,6 +2248,11 @@ egg/gfx/eggLightObject.cpp: egg/gfx/eggLightTexture.cpp: .text start:0x804AB250 end:0x804AD448 .ctors start:0x804DB9A4 end:0x804DB9A8 + .rodata start:0x804FBC98 end:0x804FBD08 + .data start:0x8056F0B8 end:0x8056F0F0 + .sdata start:0x80574F38 end:0x80574F48 + .sdata2 start:0x8057F6C0 end:0x8057F708 + .bss start:0x80674E78 end:0x80674EF0 egg/gfx/eggLightTextureMgr.cpp: .text start:0x804AD450 end:0x804AE644 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index cdb9304c..2b45fd62 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26538,7 +26538,7 @@ CopyToG3D__Q23EGG10FogManagerCFPQ34nw4r3g3d7ScnRoot = .text:0x804A5B90; // type: SetBinaryInner__Q23EGG10FogManagerFRCQ33EGG27IBinary3Bin = .text:0x804A5C20; // type:function size:0x9C SetBinaryInner__Q23EGG10FogManagerFRCQ33EGG27IBinary3BinRCQ33EGG27IBinary3Binf = .text:0x804A5CC0; // type:function size:0xA4 GetBinaryInner__Q23EGG10FogManagerCFPQ33EGG27IBinary3Bin = .text:0x804A5D70; // type:function size:0x80 -GetBinarySize__Q23EGG10FogManagerCFv = .text:0x804A5DF0; // type:function size:0x14 +GetBinarySize__Q23EGG10FogManagerFv = .text:0x804A5DF0; // type:function size:0x14 GetBinary__Q23EGG19IBinaryCFPv = .text:0x804A5E10; // type:function size:0x140 SetBinaryBlend__Q23EGG19IBinaryFPCvPCvf = .text:0x804A5F50; // type:function size:0x10 __ct__Q23EGG7FrustumFQ33EGG7Frustum14ProjectionTypeRCQ34nw4r4math4VEC2ffQ33EGG7Frustum10CanvasMode = .text:0x804A5F60; // type:function size:0x64 @@ -26658,10 +26658,10 @@ GetBinaryInner__Q23EGG12LightTextureCFPQ33EGG29IBinary3Bin GetBinarySize__Q23EGG12LightTextureCFv = .text:0x804AD390; // type:function size:0x14 SetBinaryInner__Q23EGG29IBinaryFRCQ33EGG29IBinary3BinRCQ33EGG29IBinary3Binf = .text:0x804AD3B0; // type:function size:0x4 __sinit_\eggLightTexture_cpp = .text:0x804AD3C0; // type:function size:0x44 scope:local -@52@SetBinaryInner__Q23EGG12LightTextureFRCQ33EGG29IBinary3Bin = .text:0x804AD410; // type:function size:0x8 -@52@GetBinaryInner__Q23EGG12LightTextureCFPQ33EGG29IBinary3Bin = .text:0x804AD420; // type:function size:0x8 -@52@GetBinarySize__Q23EGG12LightTextureCFv = .text:0x804AD430; // type:function size:0x8 -@52@__dt__Q23EGG12LightTextureFv = .text:0x804AD440; // type:function size:0x8 +@44@SetBinaryInner__Q23EGG12LightTextureFRCQ33EGG29IBinary3Bin = .text:0x804AD410; // type:function size:0x8 +@44@GetBinaryInner__Q23EGG12LightTextureCFPQ33EGG29IBinary3Bin = .text:0x804AD420; // type:function size:0x8 +@44@GetBinarySize__Q23EGG12LightTextureCFv = .text:0x804AD430; // type:function size:0x8 +@44@__dt__Q23EGG12LightTextureFv = .text:0x804AD440; // type:function size:0x8 __ct__Q23EGG19LightTextureManagerFPCQ23EGG12LightManager = .text:0x804AD450; // type:function size:0x1AC __dt__Q23EGG19LightTextureManagerFv = .text:0x804AD600; // type:function size:0x90 createTexture__Q23EGG19LightTextureManagerFPCc = .text:0x804AD690; // type:function size:0x110 @@ -26698,8 +26698,8 @@ 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 -FUN_804af040 = .text:0x804AF040; // type:function size:0x164 -FUN_804af1b0 = .text:0x804AF1B0; // type:function size:0x120 +fn_804AF040__Q23EGG14PostEffectBaseFR8_GXColorRC8_GXColorbf = .text:0x804AF040; // type:function size:0x164 +fn_804AF1B0__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 @@ -37371,7 +37371,7 @@ EGG__GfxEnginer__Configuration__vtable = .data:0x8056F048; // type:object size:0 __vt__Q23EGG8IScnProc = .data:0x8056F058; // type:object size:0x10 EGG__LightManager__vtable = .data:0x8056F068; // type:object size:0x30 EGG__LightObject__vtable = .data:0x8056F098; // type:object size:0x20 -EGG__LightTexture__vtable = .data:0x8056F0B8; // type:object size:0x38 +__vt__Q23EGG12LightTexture = .data:0x8056F0B8; // type:object size:0x38 EGG__LightTextureManager__vtable = .data:0x8056F0F0; // type:object size:0x20 lbl_8056F110 = .data:0x8056F110; // type:object size:0x10 jumptable_8056F120 = .data:0x8056F120; // type:object size:0x30 scope:local @@ -39829,7 +39829,7 @@ 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 lbl_80574F30 = .sdata:0x80574F30; // type:object size:0x8 -lbl_80574F38 = .sdata:0x80574F38; // type:object size:0x2 data:2byte +sTextureSize__Q23EGG12LightTexture = .sdata:0x80574F38; // type:object size:0x2 data:2byte lbl_80574F3A = .sdata:0x80574F3A; // type:object size:0x1 data:byte lbl_80574F3C = .sdata:0x80574F3C; // type:object size:0xC lbl_80574F48 = .sdata:0x80574F48; // type:object size:0x8 data:4byte @@ -49802,7 +49802,7 @@ sCameraMtx = .bss:0x80674DF8; // type:object size:0x30 data:float lbl_80674E28 = .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 -lbl_80674EC0 = .bss:0x80674EC0; // type:object size:0x30 data:float +sMtx__3EGG = .bss:0x80674EC0; // type:object size:0x30 data:float lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0xC data:float lbl_80674F00 = .bss:0x80674F00; // type:object size:0x88 data:4byte sScreen__Q23EGG16ScreenEffectBase = .bss:0x80674F88; // type:object size:0x88 diff --git a/include/egg/gfx/eggCapTexture.h b/include/egg/gfx/eggCapTexture.h index 9f28a786..3cd05c55 100644 --- a/include/egg/gfx/eggCapTexture.h +++ b/include/egg/gfx/eggCapTexture.h @@ -10,10 +10,23 @@ struct CopyFilter { }; class CapTexture : public CpuTexture { +public: + CapTexture() {} + CapTexture(u16 width, u16 height, GXTexFmt texFmt): CpuTexture(width, height, texFmt) {} + CapTexture(const GXTexObj *pObj): CpuTexture(pObj) {} + virtual void configure() override; // at 0xC void capture(u16 x, u16 y, bool upscale, int format); + void setPixModeSync(bool enable) { + if (enable) { + mCapFlags |= 0x10; + } else { + mCapFlags &= ~0x10; + } + } + private: /* 0x18 */ u8 mCapFlags; /* 0x19 */ GXColor mClearColor; diff --git a/include/egg/gfx/eggCpuTexture.h b/include/egg/gfx/eggCpuTexture.h index 9a9418da..74d10326 100644 --- a/include/egg/gfx/eggCpuTexture.h +++ b/include/egg/gfx/eggCpuTexture.h @@ -62,7 +62,8 @@ public: u32 getTexBufferSize() const; void buildHeader() const; Header *initHeader(); - void fillNormalMapSphere(); + void fillNormalMapSphere(f32, f32); + void fillGradient(int op, int, u16, u16, const GXColor&, const GXColor&, bool, bool); UNKTYPE func_80086C8C(UNKTYPE); void allocTexBuffer(); void allocTexBufferAndHeader(); @@ -109,6 +110,17 @@ public: void setWrapT(GXTexWrapMode wrap) { mWrapT = wrap; } + + void setWrap(GXTexWrapMode wrapS, GXTexWrapMode wrapT) { + mWrapS = wrapS; + mWrapT = wrapT; + } + + void setFilt(GXTexFilter min, GXTexFilter mag) { + mMinFilt = min; + mMagFilt = mag; + } + void setMinFilt(GXTexFilter filt) { mMinFilt = filt; } diff --git a/include/egg/gfx/eggLight.h b/include/egg/gfx/eggLight.h index d34d0b5d..67692962 100644 --- a/include/egg/gfx/eggLight.h +++ b/include/egg/gfx/eggLight.h @@ -1,31 +1,12 @@ #ifndef EGG_LIGHT_H #define EGG_LIGHT_H -#include "egg/core/eggHeap.h" #include "egg/prim/eggBinary.h" #include "nw4r/types_nw4r.h" namespace EGG { -// TODO: Fill out more -class LightTexture { -public: - static void initialize(u16 textureSize, Heap *pHeap); -}; - -// TODO: Fill out more -class LightTextureManager : public IBinary { -public: - struct BinData {}; - virtual ~LightTextureManager(); - virtual void SetBinaryInner(const Bin &) override; - virtual void GetBinaryInner(Bin *) const override; - virtual size_t GetBinarySize() const override; - virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; - void replaceModelTextures(nw4r::g3d::ResMdl) const; - - void drawAndCaptureTexture(f32, f32, f32, f32); -}; +class LightTextureManager; // TODO: Fill out more class LightManager : public IBinary { diff --git a/include/egg/gfx/eggLightTexture.h b/include/egg/gfx/eggLightTexture.h index 263fbaac..e14fa4fb 100644 --- a/include/egg/gfx/eggLightTexture.h +++ b/include/egg/gfx/eggLightTexture.h @@ -1,6 +1,86 @@ #ifndef EGG_LIGHT_TEXTURE_H #define EGG_LIGHT_TEXTURE_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/math/eggVector.h" +#include "egg/prim/eggBinary.h" + +namespace EGG { + +class LightTextureManager; + +class LightTexture : public CapTexture, public IBinary { +public: + struct SubData { + /* 0x00 */ f32 mIntensity; + /* 0x04 */ u8 mGradientUsed; + /* 0x05 */ u8 field_0x05; + /* 0x06 */ u8 _0x06[2]; + }; + + // Implicit +0x10 from BinHeader + struct BinData { + /* 0x00 */ u16 mNumEntries; + /* 0x02 */ u8 field_0x02; + /* 0x03 */ u8 field_0x03; + /* 0x04 */ char mName[32]; + /* 0x24 */ u8 mType; + /* 0x25 */ u8 _0x25[7]; + /* 0x2C */ f32 field_0x2C; + /* 0x30 */ u8 _0x30[4]; + /* 0x34 */ char mName2[32]; + /* 0x54 */ f32 field_0x54; + + u8 _0x00[0x1D]; + SubData mSubData[1]; + }; + + LightTexture(const char *name, const LightTextureManager *mgr); + virtual ~LightTexture(); + + virtual void configure() override; // at 0xC + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual size_t GetBinarySize() const override; + + static void initialize(u16 textureSize, Heap *pHeap); + +private: + + f32 getFloat(u16 idx) const { + return mpFloatData[idx]; + } + + u8 getByte1(u16 idx) const { + return mpByteData1[idx]; + } + + u8 getByte2(u16 idx) const { + return mpByteData2[idx]; + } + + /* 0x30 */ const LightTextureManager *mpMgr; + /* 0x34 */ u8 mNumData; + /* 0x35 */ u8 field_0x35; + /* 0x36 */ u8 field_0x36; + /* 0x37 */ u8 mLightType; + /* 0x38 */ Vector3f field_0x38; + /* 0x44 */ f32 *mpFloatData; + /* 0x48 */ char *mpByteData1; + /* 0x4C */ char *mpByteData2; + /* 0x50 */ f32 field_0x50; + /* 0x54 */ char mName1[0x20]; + /* 0x74 */ char mName2[0x20]; + /* 0x94 */ u16 field_0x94; + /* 0x98 */ f32 field_0x98; + /* 0x9C */ u8 field_0x9C; + + static u16 sTextureSize; + static CpuTexture *spNormalEnvironment; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggLightTextureMgr.h b/include/egg/gfx/eggLightTextureMgr.h index 4acca7ce..eafa4524 100644 --- a/include/egg/gfx/eggLightTextureMgr.h +++ b/include/egg/gfx/eggLightTextureMgr.h @@ -1,6 +1,31 @@ #ifndef EGG_LIGHT_TEXTURE_MGR_H #define EGG_LIGHT_TEXTURE_MGR_H -namespace EGG {} // namespace EGG + +#include "egg/prim/eggBinary.h" +#include "nw4r/g3d/res/g3d_resmdl.h" + +namespace EGG { + +class LightTextureManager : public IBinary { +public: + struct BinData {}; + virtual ~LightTextureManager(); + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual size_t GetBinarySize() const override; + + void replaceModelTextures(nw4r::g3d::ResMdl) const; + + void drawAndCaptureTexture(f32, f32, f32, f32); + + u16 getMaxNumLightTextures() const { + return mMaxNumTextures; + } +private: + /* 0x14 */ u16 mMaxNumTextures; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index d35a1efb..ec3445b5 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -19,7 +19,7 @@ protected: f32 mOffsetY; // at 0x18 f32 mScaleX; // at 0x1C f32 mScaleY; // at 0x20 - f32 field_0x24; // at 0x24 + f32 mRotation; // at 0x24 PostEffectBase(); virtual ~PostEffectBase() {} // at 0x8 diff --git a/include/egg/prim/eggBinary.h b/include/egg/prim/eggBinary.h index f962a254..b1c17cf0 100644 --- a/include/egg/prim/eggBinary.h +++ b/include/egg/prim/eggBinary.h @@ -40,7 +40,7 @@ protected: return sizeof(Bin); } /** Load the object from binary, interpolating between values */ - virtual void SetBinaryInner(const Bin &, const Bin &, f32) = 0; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) {} virtual ~IBinary() {} diff --git a/src/egg/gfx/eggLightTexture.cpp b/src/egg/gfx/eggLightTexture.cpp index 174c6584..13f2049f 100644 --- a/src/egg/gfx/eggLightTexture.cpp +++ b/src/egg/gfx/eggLightTexture.cpp @@ -1,3 +1,187 @@ #include "egg/gfx/eggLightTexture.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggHeap.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggLightTextureMgr.h" +#include "rvl/GX/GXTypes.h" + +#include + +namespace EGG { + +#define NUM_CPU_TEX 18 + +static CpuTexture *sCpuTexArray[NUM_CPU_TEX]; +static const int sCpuTexGradientOp[NUM_CPU_TEX] = {0, 0, 0, 1, 2, 3, 4, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0}; + +static nw4r::math::MTX34 sMtx(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); + +u16 LightTexture::sTextureSize; +CpuTexture *LightTexture::spNormalEnvironment; + +static s8 lbl_80574F3A = 0xFE; + +template <> +const char *IBinary::GetBinaryType() { + return "LTEX"; +} + +template <> +int IBinary::GetVersion() { + return 3; +} + +void LightTexture::initialize(u16 textureSize, Heap *pHeap) { + if (pHeap == nullptr) { + pHeap = Heap::getCurrentHeap(); + } + sTextureSize = textureSize; + for (int i = 0; i < NUM_CPU_TEX; i++) { + sCpuTexArray[i] = new (pHeap) CpuTexture(64, 4, i < 10 ? GX_TF_I8 : GX_TF_RGBA8); + CpuTexture *tex = sCpuTexArray[i]; + tex->configure(); + tex->setWrapS(GX_REPEAT); + tex->setWrapT(GX_REPEAT); + u16 a = 32; + u16 b = 64; + switch (i) { + case 1: a = 0; break; + case 2: a = 16; break; + case 7: + a = 4; + b = 36; + break; + case 8: + a = 10; + b = 42; + break; + case 9: + a = 13; + b = 45; + break; + } + tex->allocate(pHeap); + tex->fillGradient(sCpuTexGradientOp[i], 0x73, a + 1, b - 1, DrawGX::BLACK, DrawGX::WHITE, true, true); + } + if (sTextureSize == 0x100) { + lbl_80574F3A = 1; + } else if (sTextureSize == 0x80) { + lbl_80574F3A = 0; + } else if (sTextureSize == 0x40) { + lbl_80574F3A = -1; + } else if (sTextureSize == 0x20) { + lbl_80574F3A = -2; + } else if (sTextureSize == 0x10) { + lbl_80574F3A = -3; + } else if (sTextureSize == 0x8) { + lbl_80574F3A = -4; + } else if (sTextureSize == 0x4) { + lbl_80574F3A = -5; + } + + spNormalEnvironment = new (pHeap) CpuTexture(sTextureSize, sTextureSize, GX_TF_RGBA8); + spNormalEnvironment->configure(); + spNormalEnvironment->allocate(pHeap); + spNormalEnvironment->fillNormalMapSphere(1.0f, 0.5f); + spNormalEnvironment->setFilt(GX_NEAR, GX_NEAR); + spNormalEnvironment->setWrap(GX_REPEAT, GX_REPEAT); +} + +LightTexture::LightTexture(const char *name, const LightTextureManager *mgr) + : CapTexture(sTextureSize, sTextureSize, GX_TF_RGBA8) { + mpMgr = mgr; + mNumData = mgr->getMaxNumLightTextures(); + field_0x35 = 0; + field_0x36 = 0; + mLightType = 0; + field_0x38.set(0.0f, 0.0f, 0.0f); + mpFloatData = nullptr; + mpByteData1 = nullptr; + mpByteData2 = nullptr; + field_0x50 = 1.0f; + field_0x94 = 0; + field_0x98 = 1.0f; + + size_t len = std::strlen(name); + if (len >= 0x1F) { + len = 0x1E; + } + int i = 0; + for (; i < len; i++) { + mName1[i] = name[i]; + } + mName1[len] = '\0'; + + for (size_t i = 0; i < sizeof(mName2); i++) { + mName2[i] = '\0'; + } + field_0x9C = 0; + mpFloatData = new float[mNumData]; + mpByteData1 = new char[mNumData]; + mpByteData2 = new char[mNumData]; + for (int i = 0; i < mNumData; i++) { + mpByteData2[i] = 0; + mpFloatData[i] = 1.0f; + mpByteData1[i] = 0; + } +} + +LightTexture::~LightTexture() { + delete[] mpFloatData; + delete[] mpByteData1; + delete[] mpByteData2; +} + +extern "C" bool lbl_8057685C; + +void LightTexture::configure() { + CapTexture::configure(); + if (lbl_8057685C) { + allocWithHeaderDebug(nullptr); + } else { + allocate(nullptr); + } + setWrap(GX_CLAMP, GX_CLAMP); + setPixModeSync(false); +} + +void LightTexture::SetBinaryInner(const Bin &bin) { + // Not bothering with version differences right now, + // since the game uses V3 and GetBinaryInner is enough + // for the structure +} + +void LightTexture::GetBinaryInner(Bin *pOutBin) const { + pOutBin->mData.mType = mLightType; + pOutBin->mData.mNumEntries = mNumData; + std::strncpy(pOutBin->mData.mName, mName1, sizeof(mName1)); + SubData *dat = pOutBin->mData.mSubData; + for (int i = 0; i < mNumData; i++) { + dat[i].field_0x05 = 0; + if (getByte1(i) & 1) { + dat[i].field_0x05 |= 1; + } + dat[i].mIntensity = getFloat(i); + dat[i].mGradientUsed = getByte2(i); + } + pOutBin->mData.field_0x02 = 0; + if (field_0x36 & 1) { + pOutBin->mData.field_0x02 |= 1; + } + if (field_0x36 & 2) { + pOutBin->mData.field_0x02 |= 2; + } + pOutBin->mData.field_0x03 = field_0x35; + pOutBin->mData.field_0x2C = field_0x50; + std::strcpy(pOutBin->mData.mName2, mName2); + pOutBin->mData.field_0x54 = field_0x98; +} + +size_t LightTexture::GetBinarySize() const { + return sizeof(Bin) + (mNumData - 1) * sizeof(SubData); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp index 8f0e3368..101caa72 100644 --- a/src/egg/gfx/eggPostEffectBase.cpp +++ b/src/egg/gfx/eggPostEffectBase.cpp @@ -26,7 +26,7 @@ PostEffectBase::PostEffectBase() { mOffsetY = 0.0f; mScaleX = 1.0f; mScaleY = 1.0f; - field_0x24 = 0.0f; + mRotation = 0.0f; } void PostEffectBase::draw(f32 width, f32 height) { @@ -125,7 +125,7 @@ void PostEffectBase::fn_804AF1B0(GXColor &out, const GXColor &c1, const GXColor void PostEffectBase::getBaseTexMtx(nw4r::math::MTX34 *mtx) const { f32 sin, cos; - nw4r::math::SinCosRad(&sin, &cos, field_0x24 * M_PI); + nw4r::math::SinCosRad(&sin, &cos, mRotation * M_PI); f32 zero = 0.0f; f32 scale = 1.0f; f32 f8 = zero - 0.5f; diff --git a/src/m/m3d/m3d.cpp b/src/m/m3d/m3d.cpp index 5ccdba26..f6fa0f9f 100644 --- a/src/m/m3d/m3d.cpp +++ b/src/m/m3d/m3d.cpp @@ -2,6 +2,8 @@ #include "egg/gfx/eggDrawGX.h" #include "egg/gfx/eggGfxEngine.h" +#include "egg/gfx/eggLightTexture.h" +#include "egg/gfx/eggLightTextureMgr.h" #include "egg/gfx/eggScreen.h" #include "egg/gfx/eggStateGX.h" #include "m/m_heap.h" diff --git a/src/toBeSorted/arc_callback_handler.cpp b/src/toBeSorted/arc_callback_handler.cpp index 680d8589..eb51d80d 100644 --- a/src/toBeSorted/arc_callback_handler.cpp +++ b/src/toBeSorted/arc_callback_handler.cpp @@ -1,7 +1,7 @@ #include "d/col/bg/d_bg_s.h" #include "d/col/bg/d_bg_w_kcol.h" #include "d/d_rawarchive.h" -#include "egg/gfx/eggLight.h" +#include "egg/gfx/eggLightTextureMgr.h" #include "m/m3d/m3d.h" #include "nw4r/g3d.h" // IWYU pragma: export #include "toBeSorted/arc_managers/current_stage_arc_manager.h" From 4eba49d9f8aa8059f7a1de387e2c7df2b48d82a9 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 16 Mar 2025 15:37:19 +0100 Subject: [PATCH 06/62] Rough outline for LightTextureManager --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 10 +- include/egg/gfx/eggLightTexture.h | 22 ++-- include/egg/gfx/eggLightTextureMgr.h | 34 +++++- include/egg/gfx/eggStateGX.h | 1 + include/egg/prim/eggBinary.h | 14 +-- src/egg/gfx/eggLightTexture.cpp | 2 +- src/egg/gfx/eggLightTextureMgr.cpp | 156 ++++++++++++++++++++++++++- 8 files changed, 215 insertions(+), 25 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 9ed8d492..4cc3bc24 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2256,6 +2256,7 @@ egg/gfx/eggLightTexture.cpp: egg/gfx/eggLightTextureMgr.cpp: .text start:0x804AD450 end:0x804AE644 + .data start:0x8056F0F0 end:0x8056F110 egg/gfx/eggModelEx.cpp: .text start:0x804AE650 end:0x804AEC20 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 2b45fd62..b9d8a2d0 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26665,8 +26665,8 @@ __sinit_\eggLightTexture_cpp = .text:0x804AD3C0; // type:function size:0x44 scop __ct__Q23EGG19LightTextureManagerFPCQ23EGG12LightManager = .text:0x804AD450; // type:function size:0x1AC __dt__Q23EGG19LightTextureManagerFv = .text:0x804AD600; // type:function size:0x90 createTexture__Q23EGG19LightTextureManagerFPCc = .text:0x804AD690; // type:function size:0x110 -EGG__LightTextureManager__createTextureFromBin = .text:0x804AD7A0; // type:function size:0x5C -EGG__LightTextureManager__createTexturesFromBin = .text:0x804AD800; // type:function size:0x6C +createTextureFromBin__Q23EGG19LightTextureManagerFPCv = .text:0x804AD7A0; // type:function size:0x5C +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 @@ -26677,7 +26677,7 @@ frameReset__Q23EGG19LightTextureManagerFv = .text:0x804ADC40; // type:function s drawAndCaptureTexture__Q23EGG19LightTextureManagerFffff = .text:0x804ADC80; // type:function size:0x4C8 SetBinaryInner__Q23EGG19LightTextureManagerFRCQ33EGG36IBinary3Bin = .text:0x804AE150; // type:function size:0x80 GetBinaryInner__Q23EGG19LightTextureManagerCFPQ33EGG36IBinary3Bin = .text:0x804AE1D0; // type:function size:0x90 -getLTEXfromLMAP = .text:0x804AE260; // type:function size:0xDC +getLtexFromLmap__Q23EGG19LightTextureManagerFPCvUs = .text:0x804AE260; // type:function size:0xDC FUN_804ae340 = .text:0x804AE340; // type:function size:0xBC GetBinarySize__Q23EGG19LightTextureManagerCFv = .text:0x804AE400; // type:function size:0x8 SetBinaryInner__Q23EGG36IBinaryFRCQ33EGG36IBinary3BinRCQ33EGG36IBinary3Binf = .text:0x804AE410; // type:function size:0x4 @@ -37372,7 +37372,7 @@ __vt__Q23EGG8IScnProc = .data:0x8056F058; // type:object size:0x10 EGG__LightManager__vtable = .data:0x8056F068; // type:object size:0x30 EGG__LightObject__vtable = .data:0x8056F098; // type:object size:0x20 __vt__Q23EGG12LightTexture = .data:0x8056F0B8; // type:object size:0x38 -EGG__LightTextureManager__vtable = .data:0x8056F0F0; // type:object size:0x20 +__vt__Q23EGG19LightTextureManager = .data:0x8056F0F0; // type:object size:0x1C lbl_8056F110 = .data:0x8056F110; // type:object size:0x10 jumptable_8056F120 = .data:0x8056F120; // type:object size:0x30 scope:local __vt__Q23EGG14PostEffectBase = .data:0x8056F150; // type:object size:0x1C @@ -41185,7 +41185,7 @@ lbl_805768A2 = .sbss:0x805768A2; // type:object size:0x2 data:2byte lbl_805768A4 = .sbss:0x805768A4; // type:object size:0x4 data:4byte lbl_805768A8 = .sbss:0x805768A8; // type:object size:0x4 data:4byte lbl_805768AC = .sbss:0x805768AC; // type:object size:0x1 data:byte -lbl_805768B0 = .sbss:0x805768B0; // type:object size:0x2 data:2byte +s_flag__Q23EGG7StateGX = .sbss:0x805768B0; // type:object size:0x2 data:2byte s_commandFlag__Q23EGG7StateGX = .sbss:0x805768B2; // type:object size:0x6 data:2byte lbl_805768B8 = .sbss:0x805768B8; // type:object size:0x4 data:4byte lbl_805768BC = .sbss:0x805768BC; // type:object size:0x4 data:4byte diff --git a/include/egg/gfx/eggLightTexture.h b/include/egg/gfx/eggLightTexture.h index e14fa4fb..c278e227 100644 --- a/include/egg/gfx/eggLightTexture.h +++ b/include/egg/gfx/eggLightTexture.h @@ -12,13 +12,14 @@ class LightTextureManager; class LightTexture : public CapTexture, public IBinary { public: +#pragma pack(push, 1) struct SubData { /* 0x00 */ f32 mIntensity; /* 0x04 */ u8 mGradientUsed; /* 0x05 */ u8 field_0x05; /* 0x06 */ u8 _0x06[2]; }; - + // Implicit +0x10 from BinHeader struct BinData { /* 0x00 */ u16 mNumEntries; @@ -26,29 +27,34 @@ public: /* 0x03 */ u8 field_0x03; /* 0x04 */ char mName[32]; /* 0x24 */ u8 mType; - /* 0x25 */ u8 _0x25[7]; + /* 0x25 */ u16 field_0x25; + /* 0x27 */ u8 field_0x27; + /* 0x28 */ u8 _0x28[4]; /* 0x2C */ f32 field_0x2C; /* 0x30 */ u8 _0x30[4]; /* 0x34 */ char mName2[32]; /* 0x54 */ f32 field_0x54; - - u8 _0x00[0x1D]; + u8 _0x00[0x20]; SubData mSubData[1]; }; - +#pragma pack(pop) + LightTexture(const char *name, const LightTextureManager *mgr); virtual ~LightTexture(); - + virtual void configure() override; // at 0xC virtual void SetBinaryInner(const Bin &) override; virtual void GetBinaryInner(Bin *) const override; virtual size_t GetBinarySize() const override; - + static void initialize(u16 textureSize, Heap *pHeap); -private: + const char *getName() const { + return mName1; + } +private: f32 getFloat(u16 idx) const { return mpFloatData[idx]; } diff --git a/include/egg/gfx/eggLightTextureMgr.h b/include/egg/gfx/eggLightTextureMgr.h index eafa4524..7696dd6c 100644 --- a/include/egg/gfx/eggLightTextureMgr.h +++ b/include/egg/gfx/eggLightTextureMgr.h @@ -1,29 +1,57 @@ #ifndef EGG_LIGHT_TEXTURE_MGR_H #define EGG_LIGHT_TEXTURE_MGR_H - +#include "egg/gfx/eggLightTexture.h" #include "egg/prim/eggBinary.h" #include "nw4r/g3d/res/g3d_resmdl.h" namespace EGG { +class LightManager; +class LightObject; + class LightTextureManager : public IBinary { public: - struct BinData {}; + struct BinData { + u16 mDataCount; + u8 _0x02[14]; + BinHeader mSubData[1]; + }; + LightTextureManager(const LightManager *lightMgr); virtual ~LightTextureManager(); virtual void SetBinaryInner(const Bin &) override; virtual void GetBinaryInner(Bin *) const override; virtual size_t GetBinarySize() const override; - void replaceModelTextures(nw4r::g3d::ResMdl) const; + u16 createTexture(const char *name); + bool setBinaryToTexture(const void *data); + bool deleteTexture(int idx); + void replaceModelTextures(nw4r::g3d::ResMdl) const; void drawAndCaptureTexture(f32, f32, f32, f32); + // Inofficial + static const void *getLtexFromLmap(const void *lmap, u16 index); + int createTexturesFromBin(const void *bin); + u16 createTextureFromBin(const void *bin); + u16 getMaxNumLightTextures() const { return mMaxNumTextures; } + + u16 getNumLightTextures() const { + return mTextureCount; + } + private: + /* 0x04 */ u8 field_0x04; + /* 0x06 */ u16 mTextureCount; + /* 0x08 */ LightTexture **mpTextures; + /* 0x0C */ const LightManager *mpLightMgr; + /* 0x10 */ u32 field_0x10; /* 0x14 */ u16 mMaxNumTextures; + /* 0x16 */ u8 field_0x16; + /* 0x18 */ LightObject **mpObjects; }; } // namespace EGG diff --git a/include/egg/gfx/eggStateGX.h b/include/egg/gfx/eggStateGX.h index 321586ba..fe712a3e 100644 --- a/include/egg/gfx/eggStateGX.h +++ b/include/egg/gfx/eggStateGX.h @@ -92,6 +92,7 @@ public: static u16 s_commandFlag; + static u16 s_flag; }; } // namespace EGG diff --git a/include/egg/prim/eggBinary.h b/include/egg/prim/eggBinary.h index b1c17cf0..9b517545 100644 --- a/include/egg/prim/eggBinary.h +++ b/include/egg/prim/eggBinary.h @@ -53,11 +53,17 @@ public: // These functions below are automatically provided, you should not need to // touch them to implement de-/serialization for your type. They will parse // the binary header and then invoke the above virtual functions. - void GetBinary(void *pData) const; void SetBinary(const void *); + void GetBinary(void *pData) const; void SetBinaryBlend(const void *a, const void *b, f32 blend); }; +template +void IBinary::SetBinary(const void *a) { + const Bin *pBinA = reinterpret_cast(a); + SetBinaryInner(*pBinA); +} + template void IBinary::GetBinary(void *pData) const { Bin *pBin = reinterpret_cast(pData); @@ -74,12 +80,6 @@ void IBinary::GetBinary(void *pData) const { GetBinaryInner(pBin); } -template -void IBinary::SetBinary(const void *a) { - const Bin *pBinA = reinterpret_cast(a); - SetBinaryInner(*pBinA); -} - template void IBinary::SetBinaryBlend(const void *a, const void *b, f32 blend) { const Bin *pBinA = reinterpret_cast(a); diff --git a/src/egg/gfx/eggLightTexture.cpp b/src/egg/gfx/eggLightTexture.cpp index 13f2049f..768b447f 100644 --- a/src/egg/gfx/eggLightTexture.cpp +++ b/src/egg/gfx/eggLightTexture.cpp @@ -19,7 +19,7 @@ static const int sCpuTexGradientOp[NUM_CPU_TEX] = {0, 0, 0, 1, 2, 3, 4, 0, 5, 5, static nw4r::math::MTX34 sMtx(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); -u16 LightTexture::sTextureSize; +u16 LightTexture::sTextureSize = 0x20; CpuTexture *LightTexture::spNormalEnvironment; static s8 lbl_80574F3A = 0xFE; diff --git a/src/egg/gfx/eggLightTextureMgr.cpp b/src/egg/gfx/eggLightTextureMgr.cpp index 6d8d0928..5aee8709 100644 --- a/src/egg/gfx/eggLightTextureMgr.cpp +++ b/src/egg/gfx/eggLightTextureMgr.cpp @@ -1,3 +1,157 @@ #include "egg/gfx/eggLightTextureMgr.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggLightTexture.h" +#include "egg/gfx/eggStateGX.h" + +#include + +namespace EGG { + +LightTextureManager::LightTextureManager(const LightManager *lightMgr) { + field_0x04 = 0x78; + mTextureCount = 0; + mpTextures = nullptr; + mpLightMgr = lightMgr; + field_0x10 = 0; + mMaxNumTextures = 0x80; + field_0x16 = 1; + mpObjects = nullptr; + mpTextures = new LightTexture *[0x80]; + for (int i = 0; i < 0x80; i++) { + mpTextures[i] = nullptr; + } + + mpObjects = new LightObject *[mMaxNumTextures]; + for (int i = 0; i < mMaxNumTextures; i++) { + mpObjects[i] = nullptr; + } + + if ((StateGX::s_flag & 0x40) != 0) { + field_0x04 |= 0x80; + field_0x04 &= ~0x40; + field_0x16 = 3; + } +} + +LightTextureManager::~LightTextureManager() { + for (int i = 0; i < 0x80; i++) { + deleteTexture(i); + } + delete[] mpTextures; + delete[] mpObjects; +} + +u16 LightTextureManager::createTexture(const char *name) { + // Check if one already exists with the same name + for (int i = 0; i < getNumLightTextures(); i++) { + if (mpTextures[i] != nullptr && !strcmp(name, mpTextures[i]->getName())) { + return i; + } + } + + // Find a hole to fill + int targetPosition = getNumLightTextures(); + for (int i = 0; i < getNumLightTextures(); i++) { + if (mpTextures[i] == nullptr) { + targetPosition = i; + } + } + if (targetPosition == getNumLightTextures()) { + mTextureCount++; + } + LightTexture *tex = new LightTexture(name, this); + mpTextures[targetPosition] = tex; + tex->configure(); + return targetPosition; +} + +u16 LightTextureManager::createTextureFromBin(const void *bin) { + const LightTexture::Bin *data = reinterpret_cast(bin); + u16 idx = createTexture(data->mData.mName); + mpTextures[idx]->SetBinary(data); + return idx; +} + +int LightTextureManager::createTexturesFromBin(const void *bin) { + const LightTextureManager::Bin *data = reinterpret_cast(bin); + // Moderate inefficiency here - this algorithm has quadratic runtime + // since we always search from the beginning + for (int i = 0; i < data->mData.mDataCount; i++) { + const void *subData = getLtexFromLmap(data, (u16)i); + createTextureFromBin(subData); + } + return data->mData.mDataCount; +} + +bool LightTextureManager::deleteTexture(int idx) { + if (0 <= idx && idx < 0x80) { + if (mpTextures[idx] != nullptr) { + delete mpTextures[idx]; + mpTextures[idx] = nullptr; + return true; + } + } + return false; +} + +bool LightTextureManager::setBinaryToTexture(const void *data) { + const LightTexture::Bin *bin = reinterpret_cast(data); + for (int i = 0; i < getNumLightTextures(); i++) { + if (!std::strcmp(bin->mData.mName, mpTextures[i]->getName())) { + mpTextures[i]->SetBinary(bin); + return true; + } + } + return false; +} + +void LightTextureManager::SetBinaryInner(const Bin &bin) { + if (bin.mHeader.mVersion != 0) { + return; + } + const char *buf = reinterpret_cast(bin.mData.mSubData); + for (int i = 0; i < bin.mData.mDataCount; i++) { + const BinHeader *hdr = reinterpret_cast(buf); + setBinaryToTexture(buf); + buf += hdr->mSize; + } +} + +void LightTextureManager::GetBinaryInner(Bin *pOutBin) const { + int count = 0; + char *buf = reinterpret_cast(pOutBin->mData.mSubData); + for (int i = 0; i < getNumLightTextures(); i++) { + mpTextures[i]->GetBinary(buf); + BinHeader *hdr = reinterpret_cast(buf); + // This is where the actually written size is added to the whole object + pOutBin->mHeader.mSize += hdr->mSize; + buf += hdr->mSize; + count++; + } + pOutBin->mData.mDataCount = count; +} + +// Performs a linear search through the data to find the offset for the given index +const void *LightTextureManager::getLtexFromLmap(const void *lmap, u16 index) { + // A bit awkward but it matches + const BinHeader *buf = nullptr; + const Bin *bin = reinterpret_cast(lmap); + if (bin->mHeader.mVersion == 0 && index < bin->mData.mDataCount) { + buf = bin->mData.mSubData; + for (int i = 0; i < index; i++) { + buf = reinterpret_cast(reinterpret_cast(buf) + buf->mSize); + } + } + + return buf; +} + +size_t LightTextureManager::GetBinarySize() const { + // Contrary to the other dynamically-sized Bins, this only + // returns the fixed size. GetBinaryInner will add the dynamic + // parts when writing. + return sizeof(Bin) - sizeof(BinHeader); +} + +} // namespace EGG From 82939548fb6eba7cbc9286078119778bb8d535c6 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 16 Mar 2025 16:35:42 +0100 Subject: [PATCH 07/62] TextureBuffer copied from OGWS with some changes --- config/SOUE01/splits.txt | 2 + config/SOUE01/symbols.txt | 24 ++-- configure.py | 2 +- include/egg/gfx/eggCapTexture.h | 4 + include/egg/gfx/eggCpuTexture.h | 4 +- include/egg/gfx/eggStateGX.h | 4 + include/egg/gfx/eggTextureBuffer.h | 56 +++++++- src/egg/gfx/eggTextureBuffer.cpp | 197 ++++++++++++++++++++++++++++- 8 files changed, 276 insertions(+), 17 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 4cc3bc24..76c6db02 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2307,6 +2307,8 @@ egg/gfx/eggStateGX.cpp: egg/gfx/eggTextureBuffer.cpp: .text start:0x804B53F0 end:0x804B59DC + .data start:0x8056F2B0 end:0x8056F2C0 + .sbss start:0x805768B8 end:0x805768D8 egg/audio/eggAudioArcPlayerMgr.cpp: .text start:0x804B59E0 end:0x804B641C diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index b9d8a2d0..d74986e8 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26797,8 +26797,8 @@ initialize__Q23EGG13TextureBufferFUlPQ23EGG4Heap = .text:0x804B55E0; // type:fun getNotJoin__Q23EGG13TextureBufferFv = .text:0x804B5710; // type:function size:0x28 alloc__Q23EGG13TextureBufferFUl = .text:0x804B5740; // type:function size:0x164 alloc__Q23EGG13TextureBufferFUsUs9_GXTexFmt = .text:0x804B58B0; // type:function size:0xA4 -FUN_804b5960 = .text:0x804B5960; // type:function size:0x8 -FUN_804b5970 = .text:0x804B5970; // type:function size:0x8 +setIncludesHeader__Q23EGG13TextureBufferFb = .text:0x804B5960; // type:function size:0x8 +includesHeader__Q23EGG13TextureBufferFv = .text:0x804B5970; // type:function size:0x8 __dt__Q23EGG13TextureBufferFv = .text:0x804B5980; // type:function size:0x5C __ct__Q23EGG9ArcPlayerFPQ34nw4r3snd18SoundArchivePlayerPQ34nw4r3snd9SoundHeap = .text:0x804B59E0; // type:function size:0x88 __dt__Q23EGG9ArcPlayerFv = .text:0x804B5A70; // type:function size:0x74 @@ -37386,7 +37386,7 @@ sTVModeInfo__Q23EGG6Screen = .data:0x8056F230; // type:object size:0x24 data:2by EGG__Screen__vtable = .data:0x8056F254; // type:object size:0x14 __vt__Q23EGG16ScreenEffectBase = .data:0x8056F268; // type:object size:0xC lbl_8056F278 = .data:0x8056F278; // type:object size:0x38 -lbl_8056F2B0 = .data:0x8056F2B0; // type:object size:0x10 +__vt__Q23EGG13TextureBuffer = .data:0x8056F2B0; // type:object size:0x10 __vt__Q23EGG9ArcPlayer = .data:0x8056F2C0; // type:object size:0x5C __vt__Q23EGG14SimpleAudioMgr = .data:0x8056F320; // type:object size:0xA4 __vt__Q23EGG9IAudioMgr = .data:0x8056F3C8; // type:object size:0x10 scope:weak @@ -41184,16 +41184,16 @@ lbl_805768A0 = .sbss:0x805768A0; // type:object size:0x2 data:2byte lbl_805768A2 = .sbss:0x805768A2; // type:object size:0x2 data:2byte lbl_805768A4 = .sbss:0x805768A4; // type:object size:0x4 data:4byte lbl_805768A8 = .sbss:0x805768A8; // type:object size:0x4 data:4byte -lbl_805768AC = .sbss:0x805768AC; // type:object size:0x1 data:byte +sDefaultTexColor__Q23EGG7StateGX = .sbss:0x805768AC; // type:object size:0x1 data:byte s_flag__Q23EGG7StateGX = .sbss:0x805768B0; // type:object size:0x2 data:2byte s_commandFlag__Q23EGG7StateGX = .sbss:0x805768B2; // type:object size:0x6 data:2byte -lbl_805768B8 = .sbss:0x805768B8; // type:object size:0x4 data:4byte -lbl_805768BC = .sbss:0x805768BC; // type:object size:0x4 data:4byte -lbl_805768C0 = .sbss:0x805768C0; // type:object size:0x4 data:4byte -lbl_805768C4 = .sbss:0x805768C4; // type:object size:0x4 data:4byte -lbl_805768C8 = .sbss:0x805768C8; // type:object size:0x4 data:4byte -lbl_805768CC = .sbss:0x805768CC; // type:object size:0x4 data:4byte -lbl_805768D0 = .sbss:0x805768D0; // type:object size:0x8 data:byte +spHead__Q23EGG13TextureBuffer = .sbss:0x805768B8; // type:object size:0x4 data:4byte +spTailNotJoin__Q23EGG13TextureBuffer = .sbss:0x805768BC; // type:object size:0x4 data:4byte +spBufferAll__Q23EGG13TextureBuffer = .sbss:0x805768C0; // type:object size:0x4 data:4byte +sBufferAllSize__Q23EGG13TextureBuffer = .sbss:0x805768C4; // type:object size:0x4 data:4byte +sBufferSize__Q23EGG13TextureBuffer = .sbss:0x805768C8; // type:object size:0x4 data:4byte +sBufferRestSizeMin__Q23EGG13TextureBuffer = .sbss:0x805768CC; // type:object size:0x4 data:4byte +sIncludesHeader__Q23EGG13TextureBuffer = .sbss:0x805768D0; // type:object size:0x1 data:byte sAudioRmtSpeakerConnectCanncelSw__Q23EGG18AudioRmtSpeakerMgr = .sbss:0x805768D8; // type:object size:0x1 data:byte mTaskFinishCount__Q23EGG18AudioRmtSpeakerMgr = .sbss:0x805768DC; // type:object size:0x4 data:4byte mTaskRequestCount__Q23EGG18AudioRmtSpeakerMgr = .sbss:0x805768E0; // type:object size:0x4 data:4byte @@ -49814,7 +49814,7 @@ lbl_806750A0 = .bss:0x806750A0; // type:object size:0x20 lbl_806750C0 = .bss:0x806750C0; // type:object size:0xA8 data:4byte lbl_80675168 = .bss:0x80675168; // type:object size:0x18 lbl_80675180 = .bss:0x80675180; // type:object size:0x10 -lbl_80675190 = .bss:0x80675190; // type:object size:0x200 data:4byte +spBufferTable__Q23EGG13TextureBuffer = .bss:0x80675190; // type:object size:0x200 data:4byte sTasks__Q23EGG18AudioRmtSpeakerMgr = .bss:0x80675390; // type:object size:0xF0 sMoveParamMgr__Q23EGG12AudioUtility = .bss:0x80675480; // type:object size:0xC lbl_80675490 = .bss:0x80675490; // type:object size:0x10 diff --git a/configure.py b/configure.py index e6d9ba62..80c0611a 100644 --- a/configure.py +++ b/configure.py @@ -901,7 +901,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggScreenEffectBlur.cpp"), # Unknown Guess Object(NonMatching, "egg/gfx/eggStateEfb.cpp"), Object(NonMatching, "egg/gfx/eggStateGX.cpp"), - Object(NonMatching, "egg/gfx/eggTextureBuffer.cpp"), + Object(Matching, "egg/gfx/eggTextureBuffer.cpp"), ], ), EGGLib( diff --git a/include/egg/gfx/eggCapTexture.h b/include/egg/gfx/eggCapTexture.h index 3cd05c55..cedc5ce1 100644 --- a/include/egg/gfx/eggCapTexture.h +++ b/include/egg/gfx/eggCapTexture.h @@ -27,6 +27,10 @@ public: } } + void setClearColor(const GXColor &clr) { + mClearColor = clr; + } + private: /* 0x18 */ u8 mCapFlags; /* 0x19 */ GXColor mClearColor; diff --git a/include/egg/gfx/eggCpuTexture.h b/include/egg/gfx/eggCpuTexture.h index 74d10326..2fac0978 100644 --- a/include/egg/gfx/eggCpuTexture.h +++ b/include/egg/gfx/eggCpuTexture.h @@ -132,8 +132,8 @@ public: return (Header *)((u8 *)dataPtr - sizeof(Header)); } - char *getBuffer() const { - return mpBuffer; + void *getBuffer() const { + return dataPtr; } void setBuffer(void *pBuffer); diff --git a/include/egg/gfx/eggStateGX.h b/include/egg/gfx/eggStateGX.h index fe712a3e..e575dcc8 100644 --- a/include/egg/gfx/eggStateGX.h +++ b/include/egg/gfx/eggStateGX.h @@ -2,6 +2,7 @@ #define EGG_STATE_GX_H #include "common.h" +#include "rvl/GX/GXTypes.h" #include "rvl/GX.h" // IWYU pragma: export namespace EGG { @@ -54,6 +55,8 @@ public: bool old; }; + static GXColor& getDefaultTexColor() { return sDefaultTexColor; } + static void initialize(u16, u16, GXColor, GXPixelFmt); static void frameInit(); static void textureInit(); // Guess for 804b4810 @@ -93,6 +96,7 @@ public: static u16 s_commandFlag; static u16 s_flag; + static GXColor sDefaultTexColor; }; } // namespace EGG diff --git a/include/egg/gfx/eggTextureBuffer.h b/include/egg/gfx/eggTextureBuffer.h index bf648ebb..3328a4ad 100644 --- a/include/egg/gfx/eggTextureBuffer.h +++ b/include/egg/gfx/eggTextureBuffer.h @@ -1,6 +1,60 @@ #ifndef EGG_TEXTURE_BUFFER_H #define EGG_TEXTURE_BUFFER_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggCapTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class TextureBuffer : public CapTexture { +public: + enum EBufferState { + STATE_FREE, + STATE_ALLOCED + }; + + static void initialize(u32, Heap *); + static TextureBuffer *getNotJoin(); + + static void append(TextureBuffer *buf) { + if (spTailNotJoin != NULL) { + spTailNotJoin->mpNext = buf; + } + + buf->mpPrev = spTailNotJoin; + buf->mpNext = NULL; + + spTailNotJoin = buf; + } + + TextureBuffer(); + virtual ~TextureBuffer() {} // at 0x8 + virtual void configure(); // at 0xC + + void alloc(u32 size); + static TextureBuffer *alloc(u16 w, u16 h, GXTexFmt fmt); + void free(); + +private: + static bool includesHeader(); + static void setIncludesHeader(bool); + + u32 mSize; // at 0x2C + EBufferState mState; // at 0x30 + TextureBuffer *mpNext; // at 0x34 + TextureBuffer *mpPrev; // at 0x38 + + static const int NUM_BUFFERS = 128; + static TextureBuffer *spHead; + static TextureBuffer *spTailNotJoin; + static char *spBufferAll; + static u32 sBufferAllSize; + static u32 sBufferSize; + static u32 sBufferRestSizeMin; + static bool sIncludesHeader; + static TextureBuffer *spBufferTable[NUM_BUFFERS]; +}; + +} // namespace EGG #endif diff --git a/src/egg/gfx/eggTextureBuffer.cpp b/src/egg/gfx/eggTextureBuffer.cpp index ed1b41e1..d8489705 100644 --- a/src/egg/gfx/eggTextureBuffer.cpp +++ b/src/egg/gfx/eggTextureBuffer.cpp @@ -1,3 +1,198 @@ #include "egg/gfx/eggTextureBuffer.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +TextureBuffer::TextureBuffer() : mSize(0), mState(STATE_FREE), mpNext(nullptr), mpPrev(nullptr) {} + +void TextureBuffer::configure() { + CapTexture::configure(); + setClearColor(StateGX::getDefaultTexColor()); + setWrap(GX_CLAMP, GX_CLAMP); + setFilt(GX_LINEAR, GX_LINEAR); + setPixModeSync(true); +} + +// Allow buffer to be reclaimed +void TextureBuffer::free() { + mState = STATE_FREE; + sBufferSize += mSize; + + // Check if previous buffer is reclaimable + if (mpPrev != nullptr && mpPrev->mState == STATE_FREE) { + // Merge with previous buffer + mSize += mpPrev->mSize; + setBuffer((u8 *)getBuffer() - mpPrev->mSize); + + // Append reusable buffer + TextureBuffer *beforeAppend = mpPrev->mpPrev; + append(mpPrev); + + // Repair mpPrev link + mpPrev = beforeAppend; + if (beforeAppend != nullptr) { + beforeAppend->mpNext = this; + } else { + spHead = this; + } + } + + // Check if next buffer is reclaimable + if (mpNext != nullptr && mpNext->mState == STATE_FREE) { + // Merge with next buffer + mSize += mpNext->mSize; + + // Append reusable buffer + TextureBuffer *afterAppend = mpNext->mpNext; + append(mpNext); + + // Repair mpNext link + mpNext = afterAppend; + if (afterAppend != nullptr) { + afterAppend->mpPrev = this; + } + } +} + +// Alloc list buffer +void TextureBuffer::initialize(u32 size, Heap *heap_) { + Heap *heap = heap_ == nullptr ? Heap::getCurrentHeap() : heap_; + if (includesHeader()) { + size += 0x20; + } + + sBufferAllSize = size; + spBufferAll = new (heap, 32) char[size]; + + if (includesHeader()) { + spBufferAll += 0x20; + } + + sBufferSize = size; + sBufferRestSizeMin = size; + spTailNotJoin = nullptr; + for (int i = 0; i < NUM_BUFFERS; i++) { + spBufferTable[i] = new TextureBuffer(); + spBufferTable[i]->configure(); + append(spBufferTable[i]); + } + + // Initialize head + spHead = getNotJoin(); + spHead->mState = STATE_FREE; + spHead->mSize = size; + spHead->setBuffer(spBufferAll); +} + +// Remove and return buffer at list end +TextureBuffer *TextureBuffer::getNotJoin() { + TextureBuffer *p_buffer = spTailNotJoin; + + // Move list tail back + spTailNotJoin = spTailNotJoin->mpPrev; + if (spTailNotJoin != nullptr) { + spTailNotJoin->mpNext = nullptr; + } + + // Pop old tail + p_buffer->mpPrev = nullptr; + return p_buffer; +} + +// Attempt to alloc buffer of specified size +void TextureBuffer::alloc(u32 size) { + size = ROUND_UP(size, 0x20); + + sBufferSize -= size; + if (sBufferSize < sBufferRestSizeMin) { + sBufferRestSizeMin = sBufferSize; + } + + // Try to find a free buffer with at least the requested size + for (TextureBuffer *p_list = spHead; p_list != nullptr; p_list = p_list->mpNext) { + if (p_list->mState == STATE_FREE && p_list->mSize >= size) { + // Assign free buffer data to new buffer + mState = STATE_ALLOCED; + mSize = size; + + u8 *buffer = (u8 *)p_list->getBuffer(); + if (includesHeader()) { + setBuffer(buffer); + if (buffer != nullptr) { + setFlag(HAS_HEADER); + } + } else { + setBuffer(buffer); + } + + // Prepend new buffer before old buffer + mpNext = p_list; + TextureBuffer *oldPrev = p_list->mpPrev; + mpPrev = oldPrev; + + // Fix this->prev link + if (oldPrev != nullptr) { + oldPrev->mpNext = this; + } else { + // nullptr prev buffer must be list head + + spHead = this; + } + + // Remove requested size from old buffer + p_list->mSize -= size; + + // Free old buffer if now empty + if (p_list->mSize == 0) { + if (p_list->mpNext != nullptr) { + p_list->mpNext->mpPrev = this; + } + mpNext = p_list->mpNext; + append(p_list); + } + // Adjust old buffer by requested size + else { + p_list->setBuffer(buffer + size); + p_list->mpPrev = this; + } + + return; + } + } +} + +TextureBuffer *TextureBuffer::alloc(u16 width, u16 height, GXTexFmt fmt) { + if (width == 0 || height == 0) { + return nullptr; + } + TextureBuffer *tex = getNotJoin(); + tex->setWidth(width); + tex->setHeight(height); + tex->setFormat(fmt); + tex->configure(); + tex->alloc(GXGetTexBufferSize(tex->getWidth(), tex->getHeight(), tex->getFormat(), false, 1)); + return tex; +} + +void TextureBuffer::setIncludesHeader(bool b) { + sIncludesHeader = b; +} + +bool TextureBuffer::includesHeader() { + return sIncludesHeader; +} + +TextureBuffer *TextureBuffer::spHead; +TextureBuffer *TextureBuffer::spTailNotJoin; +char *TextureBuffer::spBufferAll; +u32 TextureBuffer::sBufferAllSize; +u32 TextureBuffer::sBufferSize; +u32 TextureBuffer::sBufferRestSizeMin; +bool TextureBuffer::sIncludesHeader; + +} // namespace EGG From 540abd8cd172a114dd24e7721b5e15c8a442dc49 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 16 Mar 2025 18:55:59 +0100 Subject: [PATCH 08/62] Parts of ModelEx --- config/SOUE01/splits.txt | 4 +- config/SOUE01/symbols.txt | 16 ++++---- include/egg/gfx/eggModelEx.h | 61 +++++++++++++++++++++++++++- src/egg/gfx/eggModelEx.cpp | 78 +++++++++++++++++++++++++++++++++++- 4 files changed, 148 insertions(+), 11 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 76c6db02..dbcdfd2d 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2174,7 +2174,7 @@ egg/gfx/eggPalette.cpp: egg/gfx/eggTexture.cpp: .text start:0x8049CB50 end:0x8049CFE4 -egg/gfx/eggUnk1.cpp: +egg/gfx/eggAnalizeDL.cpp: .text start:0x8049CFF0 end:0x8049D7C0 egg/gfx/eggCapTexture.cpp: @@ -2260,6 +2260,8 @@ egg/gfx/eggLightTextureMgr.cpp: egg/gfx/eggModelEx.cpp: .text start:0x804AE650 end:0x804AEC20 + .data start:0x8056F110 end:0x8056F120 + .sdata start:0x80574F48 end:0x80574F60 egg/gfx/eggPostEffectBase.cpp: .text start:0x804AEC20 end:0x804AF4B4 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index d74986e8..96287d5a 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26538,7 +26538,7 @@ CopyToG3D__Q23EGG10FogManagerCFPQ34nw4r3g3d7ScnRoot = .text:0x804A5B90; // type: SetBinaryInner__Q23EGG10FogManagerFRCQ33EGG27IBinary3Bin = .text:0x804A5C20; // type:function size:0x9C SetBinaryInner__Q23EGG10FogManagerFRCQ33EGG27IBinary3BinRCQ33EGG27IBinary3Binf = .text:0x804A5CC0; // type:function size:0xA4 GetBinaryInner__Q23EGG10FogManagerCFPQ33EGG27IBinary3Bin = .text:0x804A5D70; // type:function size:0x80 -GetBinarySize__Q23EGG10FogManagerFv = .text:0x804A5DF0; // type:function size:0x14 +GetBinarySize__Q23EGG10FogManagerCFv = .text:0x804A5DF0; // type:function size:0x14 GetBinary__Q23EGG19IBinaryCFPv = .text:0x804A5E10; // type:function size:0x140 SetBinaryBlend__Q23EGG19IBinaryFPCvPCvf = .text:0x804A5F50; // type:function size:0x10 __ct__Q23EGG7FrustumFQ33EGG7Frustum14ProjectionTypeRCQ34nw4r4math4VEC2ffQ33EGG7Frustum10CanvasMode = .text:0x804A5F60; // type:function size:0x64 @@ -26684,10 +26684,10 @@ SetBinaryInner__Q23EGG36IBinaryFRCQ33EGG36IBinaryFPCv = .text:0x804AE420; // type:function size:0x10 GetBinary__Q23EGG29IBinaryCFPv = .text:0x804AE430; // type:function size:0x214 __ct__Q23EGG7ModelExFPQ34nw4r3g3d6ScnObj = .text:0x804AE650; // type:function size:0x1C8 -EGG__ModelEx__getShapeMinMax = .text:0x804AE820; // type:function size:0x228 -EGG__ModelEx__calcWorld = .text:0x804AEA50; // type:function size:0xF0 -EGG__ModelEx__getResMdl = .text:0x804AEB40; // type:function size:0x48 -EGG__ModelEx__getResShp = .text:0x804AEB90; // type:function size:0x90 +getShapeMinMax__Q23EGG7ModelExFUsPQ34nw4r4math4VEC3PQ34nw4r4math4VEC3b = .text:0x804AE820; // type:function size:0x228 +calcWorld__Q23EGG7ModelExCFPQ34nw4r4math5MTX34PCQ34nw4r4math5MTX34 = .text:0x804AEA50; // type:function size:0xF0 +getResMdl__Q23EGG7ModelExCFUs = .text:0x804AEB40; // type:function size:0x48 +getResShp__Q23EGG7ModelExCFUs = .text:0x804AEB90; // type:function size:0x90 __ct__Q23EGG14PostEffectBaseFv = .text:0x804AEC20; // type:function size:0x5C draw__Q23EGG14PostEffectBaseFff = .text:0x804AEC80; // type:function size:0x94 fn_804AED20__Q23EGG14PostEffectBaseFv = .text:0x804AED20; // type:function size:0x60 @@ -29127,7 +29127,7 @@ TYPE_NAME__Q34nw4r3g3d8ScnGroup = .rodata:0x804F7B10; // type:object size:0x10 TYPE_NAME__Q34nw4r3g3d7ScnRoot = .rodata:0x804F7B20; // type:object size:0x10 TYPE_NAME__Q34nw4r3g3d12ScnMdlSimple = .rodata:0x804F7B30; // type:object size:0x14 TYPE_NAME__Q34nw4r3g3d6ScnMdl = .rodata:0x804F7B48; // type:object size:0xC -TYPE_NAME__Q34nw4r3g3d13ScnMdlMat1Shp = .rodata:0x804F7B58; // type:object size:0x18 +TYPE_NAME__Q34nw4r3g3d14ScnMdl1Mat1Shp = .rodata:0x804F7B58; // type:object size:0x18 TYPE_NAME__Q34nw4r3g3d7ScnProc = .rodata:0x804F7B70; // type:object size:0x10 lbl_804F7B80 = .rodata:0x804F7B80; // type:object size:0x460 lbl_804F7FE0 = .rodata:0x804F7FE0; // type:object size:0x3CC @@ -39832,9 +39832,9 @@ lbl_80574F30 = .sdata:0x80574F30; // type:object size:0x8 sTextureSize__Q23EGG12LightTexture = .sdata:0x80574F38; // type:object size:0x2 data:2byte lbl_80574F3A = .sdata:0x80574F3A; // type:object size:0x1 data:byte lbl_80574F3C = .sdata:0x80574F3C; // type:object size:0xC -lbl_80574F48 = .sdata:0x80574F48; // type:object size:0x8 data:4byte +sByteCodeCalcStr__Q23EGG7ModelEx = .sdata:0x80574F48; // type:object size:0x8 data:4byte lbl_80574F50 = .sdata:0x80574F50; // type:object size:0x8 data:string -lbl_80574F58 = .sdata:0x80574F58; // type:object size:0x8 data:4byte +sByteCodeMixStr__Q23EGG7ModelEx = .sdata:0x80574F58; // type:object size:0x8 data:4byte lbl_80574F60 = .sdata:0x80574F60; // type:object size:0x4 data:4byte lbl_80574F64 = .sdata:0x80574F64; // type:object size:0x4 data:4byte sAudioRmtSpeakerWpadVolume__Q23EGG18AudioRmtSpeakerMgr = .sdata:0x80574F68; // type:object size:0x1 data:byte diff --git a/include/egg/gfx/eggModelEx.h b/include/egg/gfx/eggModelEx.h index 9fc2283b..5ef3fdb3 100644 --- a/include/egg/gfx/eggModelEx.h +++ b/include/egg/gfx/eggModelEx.h @@ -1,6 +1,65 @@ #ifndef EGG_MODEL_EX_H #define EGG_MODEL_EX_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/egg_types.h" +#include "nw4r/g3d/g3d_scnobj.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +namespace EGG { + +class ModelEx { +public: + enum EType { + cType_ScnMdlSimple, + cType_ScnMdl, + cType_ScnMdl1Mat1Shp, + cType_ScnProcModel, + cType_ScnRfl, + cType_None + }; + + enum EFlag { + cFlag_HasOriginalBV = (1 << 0) + }; + + enum EDrawShape { + cDrawShape_None = (1 << 0) + }; + +private: + nw4r::g3d::ScnObj *mScnObj; // at 0x0 + EType mType; // at 0x4 + u16 mFlag; // at 0x8 + ModelBoundingInfo *mpBoundingInfo; // at 0xC + + static u32 sDrawFlag; + static const char *sByteCodeCalcStr; + static const char *sByteCodeMixStr; + +public: + ModelEx(nw4r::g3d::ScnObj *); + void getShapeMinMax(u16, nw4r::math::VEC3 *, nw4r::math::VEC3 *, bool); + void calcWorld(nw4r::math::MTX34 *, const nw4r::math::MTX34 *worldMtx) const; + nw4r::g3d::ResMdl getResMdl(u16) const; + nw4r::g3d::ResShp getResShp(u16) const; + + nw4r::g3d::ScnMdl *getScnMdl() const { + return (mType == cType_ScnMdl) ? (nw4r::g3d::ScnMdl *)mScnObj : NULL; + } + + nw4r::g3d::ScnMdlSimple *getScnMdlSimple() const { + return (mType == cType_ScnMdlSimple || mType == cType_ScnMdl) ? (nw4r::g3d::ScnMdlSimple *)mScnObj : NULL; + } + + nw4r::g3d::ScnMdl1Mat1Shp *getScnMdl1Mat1Shp() const { + return (mType == cType_ScnMdl1Mat1Shp) ? (nw4r::g3d::ScnMdl1Mat1Shp *)mScnObj : NULL; + } + + void getMtxType0(nw4r::math::MTX34 *pMtx) const { + nw4r::math::MTX34Copy(pMtx, mScnObj->GetMtxPtr(nw4r::g3d::ScnObj::MTX_LOCAL)); + } +}; + +} // namespace EGG #endif diff --git a/src/egg/gfx/eggModelEx.cpp b/src/egg/gfx/eggModelEx.cpp index 4fdaae07..cd28528f 100644 --- a/src/egg/gfx/eggModelEx.cpp +++ b/src/egg/gfx/eggModelEx.cpp @@ -1,3 +1,79 @@ #include "egg/gfx/eggModelEx.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "nw4r/g3d/g3d_calcworld.h" +#include "nw4r/g3d/g3d_scnmdl.h" +#include "nw4r/g3d/g3d_scnmdl1mat1shp.h" +#include "nw4r/g3d/g3d_scnmdlsmpl.h" +#include "nw4r/g3d/res/g3d_resmdl.h" + +namespace EGG { + +using namespace nw4r; + +const char *ModelEx::sByteCodeCalcStr = "NodeTree"; +const char *ModelEx::sByteCodeMixStr = "NodeMix"; + +ModelEx::ModelEx(g3d::ScnObj *obj) + : mType(cType_None), mScnObj(g3d::G3dObj::DynamicCast(obj)), mFlag(0), mpBoundingInfo(nullptr) { + if (g3d::G3dObj::DynamicCast(mScnObj) != nullptr) { + mType = cType_ScnMdl; + } else if (g3d::G3dObj::DynamicCast(mScnObj) != nullptr) { + mType = cType_ScnMdlSimple; + } else if (g3d::G3dObj::DynamicCast(mScnObj) != nullptr) { + mType = cType_ScnMdl1Mat1Shp; + } +} + +void ModelEx::getShapeMinMax(u16 shapeIndex, math::VEC3 *pMin, math::VEC3 *pMax, bool doCalcWorld) {} + +void ModelEx::calcWorld(math::MTX34 *pWorldMtxArray, const math::MTX34 *worldMtx) const { + switch (mType) { + case cType_ScnMdlSimple: + case cType_ScnMdl: { + g3d::ScnMdlSimple *pMdl = (g3d::ScnMdlSimple *)mScnObj; + // cast for regalloc + u32 *wldAttrib = (u32 *)pMdl->GetWldMtxAttribArray(); + g3d::ResMdl mdl = pMdl->GetResMdl(); + const math::MTX34 *worldMtx2 = worldMtx == nullptr ? pMdl->GetMtxPtr(g3d::ScnObj::MTX_WORLD) : worldMtx; + + g3d::CalcWorld( + pWorldMtxArray, wldAttrib, mdl.GetResByteCode(sByteCodeCalcStr), worldMtx2, mdl, nullptr, nullptr + ); + + if (mdl.GetResByteCode(sByteCodeMixStr) != nullptr) { + g3d::CalcSkinning(pWorldMtxArray, wldAttrib, mdl, mdl.GetResByteCode(sByteCodeMixStr)); + } + } break; + case cType_ScnMdl1Mat1Shp: + case cType_ScnProcModel: + case cType_ScnRfl: getMtxType0(pWorldMtxArray); break; + case cType_None: + default: break; + } +} + +g3d::ResMdl ModelEx::getResMdl(u16) const { + g3d::ScnMdlSimple *mdl = getScnMdlSimple(); + if (mdl != nullptr) { + return mdl->GetResMdl(); + } + + return g3d::ResMdl(nullptr); +} + +g3d::ResShp ModelEx::getResShp(u16 shapeIndex) const { + g3d::ScnMdlSimple *mdl = getScnMdlSimple(); + if (mdl != nullptr) { + return mdl->GetResMdl().GetResShp(shapeIndex); + } + + g3d::ScnMdl1Mat1Shp *mdl1 = getScnMdl1Mat1Shp(); + if (mdl1 != nullptr) { + return mdl1->GetResShp(); + } + + return g3d::ResShp(nullptr); +} + +} // namespace EGG From fd19da8ac80df2d8a48a40a69c7ea163d1f50ab0 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 16 Mar 2025 22:14:05 +0100 Subject: [PATCH 09/62] First CreateDisplayList attempt --- config/SOUE01/splits.txt | 1 + include/egg/gfx/eggDrawGX.h | 5 +- include/rvl/OS/OSFastCast.h | 2 +- src/egg/gfx/eggDrawGX.cpp | 196 +++++++++++++++++++++++++++++++++++- 4 files changed, 200 insertions(+), 4 deletions(-) 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 From c0dfac79f7e054f2a6dd09563d27d3530c43e4d5 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 16 Mar 2025 23:30:51 +0100 Subject: [PATCH 10/62] PostEffectMask OK --- config/SOUE01/splits.txt | 2 + config/SOUE01/symbols.txt | 8 +-- configure.py | 2 +- include/egg/gfx/eggDrawGX.h | 10 ++-- include/egg/gfx/eggPostEffectMask.h | 26 ++++++++- src/egg/gfx/eggFog.cpp | 2 +- src/egg/gfx/eggPostEffectMask.cpp | 89 ++++++++++++++++++++++++++++- 7 files changed, 126 insertions(+), 13 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 28f699b9..cb0f5cb8 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2282,6 +2282,8 @@ egg/gfx/eggPostEffectUnk2.cpp: egg/gfx/eggPostEffectMask.cpp: .text start:0x804B0AB0 end:0x804B0F60 + .data start:0x8056F1D0 end:0x8056F1F0 + .sdata2 start:0x8057F7C8 end:0x8057F7D0 egg/gfx/eggPostEffectMaskDOF.cpp: .text start:0x804B0F60 end:0x804B1BE8 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 96287d5a..6beb34a5 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26485,7 +26485,7 @@ scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x804A0E60; // type:function size:0 @8@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E80; // type:function size:0x8 @20@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E90; // type:function size:0x8 FUN_804a0ea0 = .text:0x804A0EA0; // type:function size:0x188 -FUN_804a1030 = .text:0x804A1030; // type:function size:0x40 +__dt__Q23EGG14PostEffectMaskFv = .text:0x804A1030; // type:function size:0x40 FUN_804a1070 = .text:0x804A1070; // type:function size:0x40 FUN_804a10b0 = .text:0x804A10B0; // type:function size:0x40 FUN_804a10f0 = .text:0x804A10F0; // type:function size:0x60 @@ -26711,8 +26711,8 @@ 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 -FUN_804b0ab0 = .text:0x804B0AB0; // type:function size:0x64 -FUN_804b0b20 = .text:0x804B0B20; // type:function size:0x440 +__ct__Q23EGG14PostEffectMaskFv = .text:0x804B0AB0; // type:function size:0x64 +setMaterialInternal__Q23EGG14PostEffectMaskFv = .text:0x804B0B20; // type:function size:0x440 FUN_804b0f60 = .text:0x804B0F60; // type:function size:0x160 FUN_804b10c0 = .text:0x804B10C0; // type:function size:0x330 FUN_804b13f0 = .text:0x804B13F0; // type:function size:0x174 @@ -37379,7 +37379,7 @@ __vt__Q23EGG14PostEffectBase = .data:0x8056F150; // type:object size:0x1C lbl_8056F170 = .data:0x8056F170; // type:object size:0x20 lbl_8056F190 = .data:0x8056F190; // type:object size:0x20 lbl_8056F1B0 = .data:0x8056F1B0; // type:object size:0x20 -lbl_8056F1D0 = .data:0x8056F1D0; // type:object size:0x20 +__vt__Q23EGG14PostEffectMask = .data:0x8056F1D0; // type:object size:0x1C lbl_8056F1F0 = .data:0x8056F1F0; // type:object size:0x20 lbl_8056F210 = .data:0x8056F210; // type:object size:0x20 sTVModeInfo__Q23EGG6Screen = .data:0x8056F230; // type:object size:0x24 data:2byte diff --git a/configure.py b/configure.py index 80c0611a..9e51b0f5 100644 --- a/configure.py +++ b/configure.py @@ -893,7 +893,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggPostEffectBlur.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectUnk1.cpp"), # Unknown Object(NonMatching, "egg/gfx/eggPostEffectUnk2.cpp"), # Unknown - Object(NonMatching, "egg/gfx/eggPostEffectMask.cpp"), + Object(Matching, "egg/gfx/eggPostEffectMask.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectMaskDOF.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectSimple.cpp"), Object(NonMatching, "egg/gfx/eggScreen.cpp"), diff --git a/include/egg/gfx/eggDrawGX.h b/include/egg/gfx/eggDrawGX.h index e72d2cf8..b7a4d10c 100644 --- a/include/egg/gfx/eggDrawGX.h +++ b/include/egg/gfx/eggDrawGX.h @@ -96,11 +96,11 @@ public: static u32 s_flag; - static GXColor BLACK; - static GXColor WHITE; - static GXColor GREEN; - static GXColor RED; - static GXColor BLUE; + static const GXColor BLACK; + static const GXColor WHITE; + static const GXColor GREEN; + static const GXColor RED; + static const GXColor BLUE; }; } // namespace EGG diff --git a/include/egg/gfx/eggPostEffectMask.h b/include/egg/gfx/eggPostEffectMask.h index 5af4ee11..97cfbf61 100644 --- a/include/egg/gfx/eggPostEffectMask.h +++ b/include/egg/gfx/eggPostEffectMask.h @@ -1,6 +1,30 @@ #ifndef EGG_POST_EFFECT_MASK_H #define EGG_POST_EFFECT_MASK_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggPostEffectBase.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class PostEffectMask : public PostEffectBase { +public: + PostEffectMask(); + + virtual void setMaterialInternal() override; + + GXTevScale GetTevScale() const { + return static_cast(field_0x1BC); + } + +private: + /* 0x2C */ int field_0x2C; + /* 0x30 */ GXColor mColor; + /* 0x34 */ f32 field_0x34; + /* 0x38 */ f32 field_0x38; + /* 0x3C */ u8 _0x3C[0x180]; + /* 0x1BC */ u8 field_0x1BC; +}; + +} // namespace EGG #endif diff --git a/src/egg/gfx/eggFog.cpp b/src/egg/gfx/eggFog.cpp index 4669c270..06adfc12 100644 --- a/src/egg/gfx/eggFog.cpp +++ b/src/egg/gfx/eggFog.cpp @@ -23,8 +23,8 @@ Fog::Fog() { void Fog::Reset() { // TODO mColor = DrawGX::WHITE; - mNearZ = 0.0f; mFarZ = 0.0f; + mNearZ = 0.0f; mEndZ = 0.0f; mStartZ = 0.0f; mFogType = GX_FOG_NONE; diff --git a/src/egg/gfx/eggPostEffectMask.cpp b/src/egg/gfx/eggPostEffectMask.cpp index 64833345..17d6e895 100644 --- a/src/egg/gfx/eggPostEffectMask.cpp +++ b/src/egg/gfx/eggPostEffectMask.cpp @@ -1,3 +1,90 @@ #include "egg/gfx/eggPostEffectMask.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "rvl/GX/GXAttr.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +PostEffectMask::PostEffectMask() + : mColor(DrawGX::WHITE), field_0x2C(0), field_0x34(0.0f), field_0x38(1.0f), field_0x1BC(1) {} + +void PostEffectMask::setMaterialInternal() { + bool hasTex2 = mpCapTexture2 != nullptr; + loadTextureInternal(); + GXColor resColor; + fn_804AF040(resColor, mColor, false, field_0x34); + setMatColorChannel(); + GXSetNumTexGens(2); + + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + setMatInd(); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevDirect(GX_TEVSTAGE1); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXTevScale scale = field_0x2C == 0 ? GetTevScale() : GX_CS_SCALE_1; + + GXColor c = resColor; + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, mTexMapId, GX_COLOR_NULL); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevKColor(GX_KCOLOR0, c); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_KONST, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_SUB, GX_TB_ZERO, scale, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_KONST, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_SUB, GX_TB_ZERO, scale, 1, GX_TEVPREV); + + switch (field_0x2C) { + case 0: { + if (hasTex2) { + GXSetNumTevStages(2); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, mTexMapId2, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + field_0x00 = 0; + } else { + GXSetNumTevStages(1); + field_0x00 = 10; + } + break; + } + case 1: { + if (hasTex2) { + GXSetNumTevStages(3); + scale = GetTevScale(); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, mTexMapId, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXA, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, scale, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD1, mTexMapId2, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + field_0x00 = 0; + } else { + GXSetNumTevStages(2); + scale = GetTevScale(); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, mTexMapId, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXA, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, scale, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + field_0x00 = 10; + } + break; + } + } + + setMatPE(); +} + +} // namespace EGG From 4a86d9514a2dc5452f388e8b3a9f15fd423055f8 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 16 Mar 2025 23:56:52 +0100 Subject: [PATCH 11/62] CreateDisplayList almost --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 2 +- src/egg/gfx/eggDrawGX.cpp | 68 ++++++++++++++++++--------------------- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index cb0f5cb8..278dda93 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 + .data start:0x8056EDA0 end:0x8056EE60 .sdata2 start:0x8057F440 end:0x8057F584 egg/gfx/eggDrawPathBase.cpp: diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 6beb34a5..feea3c5c 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -41147,7 +41147,7 @@ sAssertCallback2__Q23EGG6Assert = .sbss:0x805767FC; // type:object size:0x4 data sPtrOverride__Q23EGG6Assert = .sbss:0x80576800; // type:object size:0x4 data:4byte sInstantHalt__Q23EGG6Assert = .sbss:0x80576804; // type:object size:0x1 data:byte sAssertOccurred__Q23EGG6Assert = .sbss:0x80576805; // type:object size:0x1 data:byte -lbl_80576808 = .sbss:0x80576808; // type:object size:0x4 data:4byte +s_flag__Q23EGG6DrawGX = .sbss:0x80576808; // type:object size:0x4 data:4byte EGG__DrawGX__sTexMapDefault = .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 diff --git a/src/egg/gfx/eggDrawGX.cpp b/src/egg/gfx/eggDrawGX.cpp index f27d08af..0f3caa02 100644 --- a/src/egg/gfx/eggDrawGX.cpp +++ b/src/egg/gfx/eggDrawGX.cpp @@ -24,21 +24,17 @@ static void DrawCircleYPolygonFan(const nw4r::math::MTX34 &mtx, f32, u16) {} namespace EGG { +u8 sDetailLevels[] = {10, 20}; -extern "C" u8 lbl_8057F528[]; -// Halp void DrawGX::CreateDisplayList(EGG::Heap *pHeap) { - u8 tmpDisplayList[16 * 1024]; - + u8 ALIGN_DECL(32) 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) { + switch (static_cast
(i)) { case DL_0: GXSetChanMatColor(GX_COLOR0A0, RED); GXBegin(GX_LINES, GX_VTXFMT0, 2); @@ -72,24 +68,24 @@ void DrawGX::CreateDisplayList(EGG::Heap *pHeap) { case DL_4: GXDrawSphere(8, 16); break; case DL_5: case DL_6: { - u16 numSegments = dat[i - DL_5] + 1; + u16 numSegments = sDetailLevels[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 + 0.5f * nw4r::math::CosRad(radPerSegment * i), 0.5f * nw4r::math::SinRad(radPerSegment * i), 0.0f ); } break; } case DL_9: case DL_10: { - u16 numSegments = dat[i - DL_9] + 1; + u16 numSegments = sDetailLevels[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); + f32 x = 0.5f * nw4r::math::SinRad(radPerSegment * i); + f32 z = 0.5f * nw4r::math::CosRad(radPerSegment * i); GXPosition3f32(x, -0.5f, z); GXPosition3f32(2.0f * x, 0.0f, 2.0f * z); GXPosition3f32(x, 0.5f, z); @@ -97,21 +93,21 @@ void DrawGX::CreateDisplayList(EGG::Heap *pHeap) { } nw4r::math::MTX34 mtx; PSMTXTrans(mtx, 0.0f, 0.5f, 0.0f); - DrawCircleYPolygonFan(mtx, 0.0f, dat[i - DL_9]); + DrawCircleYPolygonFan(mtx, 0.0f, sDetailLevels[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]); + DrawCircleYPolygonFan(mtx, 0.0f, sDetailLevels[i - DL_9]); break; } case DL_11: case DL_12: { nw4r::math::MTX34 mtx; PSMTXIdentity(mtx); - DrawCircleYPolygonFan(mtx, 1.0f, dat[i - DL_11]); + DrawCircleYPolygonFan(mtx, 1.0f, sDetailLevels[i - DL_11]); PSMTXRotRad(mtx, M_PI, 0x7A); - DrawCircleYPolygonFan(mtx, 0.0f, dat[i - DL_11]); + DrawCircleYPolygonFan(mtx, 0.0f, sDetailLevels[i - DL_11]); break; } case DL_7: @@ -119,7 +115,7 @@ void DrawGX::CreateDisplayList(EGG::Heap *pHeap) { nw4r::math::MTX34 mtx; PSMTXIdentity(mtx); PSMTXRotRad(mtx, M_PI / 2.0f, 0x78); - DrawCircleYPolygonFan(mtx, 0.0f, dat[i - DL_7]); + DrawCircleYPolygonFan(mtx, 0.0f, sDetailLevels[i - DL_7]); break; } @@ -128,19 +124,19 @@ void DrawGX::CreateDisplayList(EGG::Heap *pHeap) { GXBegin(GX_QUADS, GX_VTXFMT0, 4); GXPosition2u8(0, 0); if (i == DL_13) { - GXCmd1u8(0); + GXPosition1x8(0); } GXPosition2u8(1, 0); if (i == DL_13) { - GXCmd1u8(1); + GXPosition1x8(1); } GXPosition2u8(2, 0); if (i == DL_13) { - GXCmd1u8(2); + GXPosition1x8(2); } GXPosition2u8(3, 0); if (i == DL_13) { - GXCmd1u8(3); + GXPosition1x8(3); } break; } @@ -150,35 +146,35 @@ void DrawGX::CreateDisplayList(EGG::Heap *pHeap) { 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); + GXPosition1x8(0); if (i == DL_16) { - GXCmd1u8(0); + GXPosition1x8(0); } - GXCmd1u8(1); + GXPosition1x8(1); if (i == DL_16) { - GXCmd1u8(1); + GXPosition1x8(1); } - GXCmd1u8(2); + GXPosition1x8(2); if (i == DL_16) { - GXCmd1u8(2); + GXPosition1x8(2); } - GXCmd1u8(3); + GXPosition1x8(3); if (i == DL_16) { - GXCmd1u8(3); + GXPosition1x8(3); } break; - case DL_MAX: - default: break; + default: break; } + u32 size = GXEndDisplayList(); - dl[i].mLen = size; - u8 *data = new (pHeap, 0x20) u8[(2 * size) - size]; - dl[i].mpList = data; + s_DL[i].mLen = size; + u8 *data = new (pHeap, 0x20) u8[size]; + s_DL[i].mpList = data; for (int j = 0; j < size; j++) { data[j] = tmpDisplayList[j]; } From aa9d6c1557e0b0e01140fbffd61c01a66ebbeae7 Mon Sep 17 00:00:00 2001 From: robojumper Date: Mon, 17 Mar 2025 00:36:41 +0100 Subject: [PATCH 12/62] Bit of progress --- src/egg/gfx/eggDrawGX.cpp | 69 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/src/egg/gfx/eggDrawGX.cpp b/src/egg/gfx/eggDrawGX.cpp index 0f3caa02..d575781c 100644 --- a/src/egg/gfx/eggDrawGX.cpp +++ b/src/egg/gfx/eggDrawGX.cpp @@ -12,13 +12,74 @@ #include "rvl/GX/GXTypes.h" #include "rvl/GX/GXVert.h" #include "rvl/MTX/mtx.h" +#include "rvl/MTX/mtxvec.h" +#include "rvl/MTX/vec.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) {} +static void DrawQuadNormal(u8 x1, u8 x2, u8 x3, u8 x4, u8 y) { + GXPosition2u8(x1, y); + GXPosition2u8(x2, y); + GXPosition2u8(x3, y); + GXPosition2u8(x4, y); +} + +static void DrawQuadLineStripNormal(u8 x1, u8 x2, u8 x3, u8 x4, u8 y) { + GXBegin(GX_LINESTRIP, GX_VTXFMT0, 5); + GXPosition2u8(x1, y); + GXPosition2u8(x2, y); + GXPosition2u8(x3, y); + GXPosition2u8(x4, y); + GXPosition2u8(x1, y); +} + +static void DrawCircleYPolygonFan(const nw4r::math::MTX34 &mtx, f32 f, u16 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); + PSMTXMultVec(mtx, v2, v2); + + GXBegin(GX_TRIANGLEFAN, GX_VTXFMT0, seg + 1); + + f32 signedStepSize = -stepSize; + + GXPosition3f32(v2.x, v2.y, v2.z); + GXPosition3f32(v1.x, v1.y, v1.z); + + for (int i = 0; i < seg; i++) { + nw4r::math::VEC3 v3( + 0.5f * nw4r::math::SinRad(signedStepSize * i), 0.0f, 0.5f * nw4r::math::CosRad(signedStepSize * i) + ); + PSMTXMultVec(mtx, v3, v3); + GXPosition3f32(v3.x, v3.y, v3.z); + + nw4r::math::VEC3 v4( + 0.5f * nw4r::math::SinRad(signedStepSize * (i - 1)), 0.0f, + 0.5f * nw4r::math::CosRad(signedStepSize * (i - 1)) + ); + nw4r::math::VEC3 v5( + 0.5f * nw4r::math::SinRad(signedStepSize * (i + 1)), 0.0f, + 0.5f * nw4r::math::CosRad(signedStepSize * (i + 1)) + ); + + PSMTXMultVec(mtx, v4, v4); + PSMTXMultVec(mtx, v5, v5); + + v4 -= v2; + v5 -= v2; + + nw4r::math::VEC3 v6; + PSVECCrossProduct(v5, v4, v6); + PSVECNormalize(v6, v6); + + GXPosition3f32(v6.x, v6.y, v6.z); + } +} } // namespace @@ -28,7 +89,7 @@ u8 sDetailLevels[] = {10, 20}; void DrawGX::CreateDisplayList(EGG::Heap *pHeap) { u8 ALIGN_DECL(32) tmpDisplayList[16 * 1024]; - + OSInitFastCast(); for (int i = 0; i < DL_MAX; i++) { From 1661ab219fd9d27165c5edc4cfd2178274cfb646 Mon Sep 17 00:00:00 2001 From: robojumper Date: Wed, 19 Mar 2025 00:27:22 +0100 Subject: [PATCH 13/62] DrawGX almost completely matching --- config/SOUE01/splits.txt | 6 +- config/SOUE01/symbols.txt | 24 +- include/egg/gfx/eggDrawGX.h | 83 +++++- include/egg/gfx/eggGXUtility.h | 15 +- src/egg/gfx/eggDrawGX.cpp | 487 ++++++++++++++++++++++++++++++++- 5 files changed, 594 insertions(+), 21 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 278dda93..1f60685e 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -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 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index feea3c5c..610e51e7 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -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 diff --git a/include/egg/gfx/eggDrawGX.h b/include/egg/gfx/eggDrawGX.h index b7a4d10c..6854ab50 100644 --- a/include/egg/gfx/eggDrawGX.h +++ b/include/egg/gfx/eggDrawGX.h @@ -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; diff --git a/include/egg/gfx/eggGXUtility.h b/include/egg/gfx/eggGXUtility.h index d36dfff1..daf49239 100644 --- a/include/egg/gfx/eggGXUtility.h +++ b/include/egg/gfx/eggGXUtility.h @@ -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 diff --git a/src/egg/gfx/eggDrawGX.cpp b/src/egg/gfx/eggDrawGX.cpp index d575781c..5b80bb56 100644 --- a/src/egg/gfx/eggDrawGX.cpp +++ b/src/egg/gfx/eggDrawGX.cpp @@ -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 From 5c67aac0f2d4f5902856e823ddec57c44888d317 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Tue, 18 Mar 2025 23:12:32 -0400 Subject: [PATCH 14/62] more sensible GX VTX ATTR typing --- src/egg/gfx/eggDrawGX.cpp | 123 ++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 64 deletions(-) diff --git a/src/egg/gfx/eggDrawGX.cpp b/src/egg/gfx/eggDrawGX.cpp index 5b80bb56..31e973e6 100644 --- a/src/egg/gfx/eggDrawGX.cpp +++ b/src/egg/gfx/eggDrawGX.cpp @@ -378,33 +378,26 @@ 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); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0xe); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 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) s16 sVtxDataType0[][3] = { + {0xE000, 0x2000, 0xE000}, + {0xE000, 0x2000, 0x2000}, + {0x2000, 0x2000, 0x2000}, + {0x2000, 0x2000, 0xE000}, + {0xE000, 0xE000, 0xE000}, + {0xE000, 0xE000, 0x2000}, + {0x2000, 0xE000, 0x2000}, + {0x2000, 0xE000, 0xE000}, }; - 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, + static const ALIGN_DECL(32) s16 sNrmDataType0[][3] = { + {0xC000, 0x0000, 0x0000}, + {0x4000, 0x0000, 0x0000}, + {0x0000, 0xC000, 0x0000}, + {0x0000, 0x4000, 0x0000}, + {0x0000, 0x0000, 0xC000}, + {0x0000, 0x0000, 0x4000}, }; // clang-format on GXSetArray(GX_VA_POS, sVtxDataType0, 6); @@ -418,37 +411,38 @@ void DrawGX::SetVtxState(EGG::DrawGX::VtxType type) { 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); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, 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_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, 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); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, 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) s16 sVtxDataType7[][2] = { + {0xE000, 0x2000}, + {0x2000, 0x2000}, + {0x2000, 0xE000}, + {0xE000, 0xE000}, }; - static const ALIGN_DECL(32) u8 sNrmDataType7[] = { - 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, + static const ALIGN_DECL(32) s16 sNrmDataType7[][3] = { + {0x0000, 0x0000, 0x4000} }; - static const ALIGN_DECL(32) u8 sTexDataType7[] = { - 0x00, 0x00, 0x01, 0x00, - 0x01, 0x01, 0x00, 0x01, + static const ALIGN_DECL(32) u8 sTexDataType7[][2] = { + {0x00, 0x00}, + {0x01, 0x00}, + {0x01, 0x01}, + {0x00, 0x01}, }; // clang-format on GXSetVtxDesc(GX_VA_POS, GX_INDEX8); @@ -456,10 +450,10 @@ void DrawGX::SetVtxState(EGG::DrawGX::VtxType type) { 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); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0xe); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 0xe); if (type == VTX_TYPE_7) { - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGB565, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0); } GXSetArray(GX_VA_POS, sVtxDataType7, 4); GXSetArray(GX_VA_NRM, sNrmDataType7, 6); @@ -469,23 +463,20 @@ void DrawGX::SetVtxState(EGG::DrawGX::VtxType type) { 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) s16 sVtxDataType9[][3] = { + {0xE000, 0x0000, 0xE000}, + {0x2000, 0x0000, 0xE000}, + {0x2000, 0x0000, 0x2000}, + {0xE000, 0x0000, 0x2000}, }; - static const ALIGN_DECL(32) u8 sNrmDataType9[] = { - 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, + static const ALIGN_DECL(32) s16 sNrmDataType9[][3] = { + {0x0000, 0x4000, 0x0000} }; // 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); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0xe); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 0xe); GXSetArray(GX_VA_POS, sVtxDataType9, 6); GXSetArray(GX_VA_NRM, sNrmDataType9, 6); break; @@ -494,13 +485,17 @@ void DrawGX::SetVtxState(EGG::DrawGX::VtxType type) { 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 sPosDataType10[][2] = { + {0x00, 0x01}, + {0x01, 0x01}, + {0x01, 0x00}, + {0x00, 0x00}, }; - static const ALIGN_DECL(32) u8 sTexDataType10[] = { - 0x00, 0x00, 0x01, 0x00, - 0x01, 0x01, 0x00, 0x01, + static const ALIGN_DECL(32) u8 sTexDataType10[][2] = { + {0x00, 0x00}, + {0x01, 0x00}, + {0x01, 0x01}, + {0x00, 0x01}, }; // clang-format on bool bVar1 = type == VTX_TYPE_11 || type == VTX_TYPE_13; @@ -513,9 +508,9 @@ void DrawGX::SetVtxState(EGG::DrawGX::VtxType type) { if (bVar2) { GXSetArray(GX_VA_TEX0, sTexDataType10, 2); } - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGB565, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_U8, 0); if (bVar2) { - GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGB565, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0); } break; } From 217851300addd1b53a8c55e7892c21acb0cc19eb Mon Sep 17 00:00:00 2001 From: robojumper Date: Wed, 19 Mar 2025 23:16:03 +0100 Subject: [PATCH 15/62] Attempt eggCamera --- config/SOUE01/splits.txt | 2 +- config/SOUE01/symbols.txt | 14 +++--- include/egg/gfx/eggCamera.h | 68 ++++++++++++++++++++++++- include/egg/gfx/eggG3DUtility.h | 7 +++ include/egg/gfx/eggLightTextureMgr.h | 3 +- src/egg/gfx/eggCamera.cpp | 75 +++++++++++++++++++++++++++- src/egg/gfx/eggLightTextureMgr.cpp | 25 ++++++++++ 7 files changed, 183 insertions(+), 11 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 1f60685e..73a15530 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2166,7 +2166,7 @@ egg/prim/eggAssert.cpp: .bss start:0x80674C60 end:0x80674D68 egg/gfx/eggCamera.cpp: - .text start:0x8049C5C0 end:0x8049CAC0 + .text start:0x8049C5C0 end:0x8049CAC8 egg/gfx/eggPalette.cpp: .text start:0x8049CAD0 end:0x8049CB44 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 610e51e7..9edae6db 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -37352,8 +37352,8 @@ __vt__Q23EGG14CoreController = .data:0x8056EC50; // type:object size:0x38 @3874 = .data:0x8056ECD0; // type:object size:0xA scope:local data:string @3878 = .data:0x8056ECDC; // type:object size:0xD scope:local data:string @3881 = .data:0x8056ECF0; // type:object size:0x10 scope:local data:string -EGG____OrthoCamera__vtable = .data:0x8056ED00; // type:object size:0x30 -EGG__LookAtCamera__vtable = .data:0x8056ED30; // type:object size:0x30 +__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 @@ -37365,7 +37365,7 @@ lbl_8056EEB0 = .data:0x8056EEB0; // type:object size:0x78 __vt__Q23EGG11DrawPathDOF = .data:0x8056EF28; // type:object size:0x78 lbl_8056EFA0 = .data:0x8056EFA0; // type:object size:0x50 __vt__Q23EGG3Fog = .data:0x8056EFF0; // type:object size:0x20 -__vt__Q23EGG10FogManager = .data:0x8056F010; // type:object size:0x20 +__vt__Q23EGG10FogManager = .data:0x8056F010; // type:object size:0x1C EGG__Frustum__vtable = .data:0x8056F030; // type:object size:0x18 EGG__GfxEnginer__Configuration__vtable = .data:0x8056F048; // type:object size:0x10 __vt__Q23EGG8IScnProc = .data:0x8056F058; // type:object size:0x10 @@ -37373,7 +37373,7 @@ EGG__LightManager__vtable = .data:0x8056F068; // type:object size:0x30 EGG__LightObject__vtable = .data:0x8056F098; // type:object size:0x20 __vt__Q23EGG12LightTexture = .data:0x8056F0B8; // type:object size:0x38 __vt__Q23EGG19LightTextureManager = .data:0x8056F0F0; // type:object size:0x1C -lbl_8056F110 = .data:0x8056F110; // type:object size:0x10 +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 @@ -39832,9 +39832,9 @@ lbl_80574F30 = .sdata:0x80574F30; // type:object size:0x8 sTextureSize__Q23EGG12LightTexture = .sdata:0x80574F38; // type:object size:0x2 data:2byte lbl_80574F3A = .sdata:0x80574F3A; // type:object size:0x1 data:byte lbl_80574F3C = .sdata:0x80574F3C; // type:object size:0xC -sByteCodeCalcStr__Q23EGG7ModelEx = .sdata:0x80574F48; // type:object size:0x8 data:4byte +sByteCodeCalcStr__Q23EGG7ModelEx = .sdata:0x80574F48; // type:object size:0x4 data:4byte lbl_80574F50 = .sdata:0x80574F50; // type:object size:0x8 data:string -sByteCodeMixStr__Q23EGG7ModelEx = .sdata:0x80574F58; // type:object size:0x8 data:4byte +sByteCodeMixStr__Q23EGG7ModelEx = .sdata:0x80574F58; // type:object size:0x4 data:4byte lbl_80574F60 = .sdata:0x80574F60; // type:object size:0x4 data:4byte lbl_80574F64 = .sdata:0x80574F64; // type:object size:0x4 data:4byte sAudioRmtSpeakerWpadVolume__Q23EGG18AudioRmtSpeakerMgr = .sdata:0x80574F68; // type:object size:0x1 data:byte @@ -48445,7 +48445,7 @@ lbl_8057FFA0 = .sbss2:0x8057FFA0; // type:object size:0x8 data:4byte lbl_8057FFA8 = .sbss2:0x8057FFA8; // type:object size:0x8 lbl_8057FFB0 = .sbss2:0x8057FFB0; // type:object size:0x8 DefaultBlackColor = .sbss2:0x8057FFB8; // type:object size:0x8 scope:local data:2byte -sBlack__3EGG = .sbss2:0x8057FFC0; // type:object size:0x8 data:byte +sBlack__3EGG = .sbss2:0x8057FFC0; // type:object size:0x4 data:byte lbl_8057FFC8 = .sbss2:0x8057FFC8; // type:object size:0x4 lbl_80580000 = .bss:0x80580000; // type:object size:0x14 data:4byte lbl_80580014 = .bss:0x80580014; // type:object size:0xC diff --git a/include/egg/gfx/eggCamera.h b/include/egg/gfx/eggCamera.h index 58937440..220d91c7 100644 --- a/include/egg/gfx/eggCamera.h +++ b/include/egg/gfx/eggCamera.h @@ -1,6 +1,72 @@ #ifndef EGG_CAMERA_H #define EGG_CAMERA_H -namespace EGG {} // namespace EGG +#include "egg/math/eggMatrix.h" +#include "egg/math/eggVector.h" +#include "nw4r/g3d/g3d_camera.h" + +namespace EGG { + +class BaseCamera { +public: + BaseCamera() {} + // Which way around? + virtual Matrix34f &getViewMatrix() = 0; + virtual const Matrix34f &getViewMatrix() const = 0; + virtual void updateMatrix(); + virtual void doUpdateMatrix() = 0; + virtual void loadMatrix() = 0; + virtual void loadOldMatrix() = 0; + virtual EGG::Vector3f getPosition() = 0; + virtual void draw(EGG::BaseCamera *cam); + virtual void doDraw() = 0; + virtual Matrix34f &getViewMatrixOld() = 0; + + void setG3DCamera(nw4r::g3d::Camera &); +}; + +class LookAtCamera : public BaseCamera { +public: + LookAtCamera() : mPosition(0.0f, 10.0f, 0.0f), mRight(0.0f, 0.0f, 0.0f), mUp(0.0f, 1.0f, 0.0f) {} + // Which way around? + virtual Matrix34f &getViewMatrix() override { + return mViewMtx; + } + virtual const Matrix34f &getViewMatrix() const override { + return mViewMtx; + } + + virtual void doUpdateMatrix() override; + virtual void loadMatrix() override; + virtual void loadOldMatrix() override; + virtual EGG::Vector3f getPosition() override { + return mPosition; + } + + virtual void doDraw() override; + virtual Matrix34f &getViewMatrixOld() override; + +protected: + /* 0x04 */ Matrix34f mViewMtx; + /* 0x34 */ Matrix34f mOtherMtx; + /* 0x64 */ Vector3f mPosition; + /* 0x70 */ Vector3f mRight; + /* 0x7C */ Vector3f mUp; +}; + +class OrthoCamera : public LookAtCamera { +public: + OrthoCamera(); + + virtual void doUpdateMatrix() override; + +private: + void update_parms(); + + /* 0x88 */ f32 field_0x88; + /* 0x8C */ f32 field_0x8C; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggG3DUtility.h b/include/egg/gfx/eggG3DUtility.h index 059261c7..cc1c9175 100644 --- a/include/egg/gfx/eggG3DUtility.h +++ b/include/egg/gfx/eggG3DUtility.h @@ -1,6 +1,8 @@ #ifndef EGG_G3D_UTILITY_H #define EGG_G3D_UTILITY_H +#include "nw4r/g3d/g3d_scnmdl.h" +#include "nw4r/g3d/res/g3d_resmat.h" #include "rvl/MEM/mem_allocator.h" namespace EGG { @@ -11,6 +13,11 @@ public: return sAllocator; } + static u16 SetTexture( + nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess param_2, char *name, GXTexObj *texObj, bool copy, + void *param_6, int param_7, int param_8 + ); + private: static MEMAllocator *sAllocator; }; diff --git a/include/egg/gfx/eggLightTextureMgr.h b/include/egg/gfx/eggLightTextureMgr.h index 7696dd6c..18e0cc8b 100644 --- a/include/egg/gfx/eggLightTextureMgr.h +++ b/include/egg/gfx/eggLightTextureMgr.h @@ -27,7 +27,8 @@ public: bool setBinaryToTexture(const void *data); bool deleteTexture(int idx); - void replaceModelTextures(nw4r::g3d::ResMdl) const; + int replaceModelTextures(nw4r::g3d::ResMdl) const; + int replaceModelTexture(u16, nw4r::g3d::ResMdl) const; void drawAndCaptureTexture(f32, f32, f32, f32); // Inofficial diff --git a/src/egg/gfx/eggCamera.cpp b/src/egg/gfx/eggCamera.cpp index ad0889b8..3e785cbf 100644 --- a/src/egg/gfx/eggCamera.cpp +++ b/src/egg/gfx/eggCamera.cpp @@ -1,3 +1,76 @@ #include "egg/gfx/eggCamera.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/math/eggMatrix.h" +#include "egg/math/eggVector.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTransform.h" + +namespace EGG { + +void BaseCamera::updateMatrix() { + doUpdateMatrix(); +} + +void EGG::BaseCamera::draw(EGG::BaseCamera *cam) { + cam->loadMatrix(); + doDraw(); +} + +void BaseCamera::setG3DCamera(nw4r::g3d::Camera &cam) { + cam.SetCameraMtxDirectly(*reinterpret_cast(&getViewMatrix())); +} + +Matrix34f &LookAtCamera::getViewMatrixOld() { + return mOtherMtx; +} + +void LookAtCamera::doUpdateMatrix() { + mOtherMtx.copyFrom(mViewMtx); + EGG::Vector3f posRight = mPosition; + posRight -= mRight; + posRight.normalise(); + + EGG::Vector3f forward = posRight.cross(mUp); + forward.normalise(); + + EGG::Vector3f up = posRight.cross(forward); + up.normalise(); + + mViewMtx.setTranslation(Vector3f((forward.dot(mPosition)), (up.dot(mPosition)), (posRight.dot(mPosition)))); + mViewMtx.setBase(0, forward); + mViewMtx.setBase(1, up); + mViewMtx.setBase(2, posRight); +} + +void LookAtCamera::doDraw() {} + +void LookAtCamera::loadMatrix() { + Matrix34f mtx; + GXLoadPosMtxImm(mViewMtx.m, 0); + mViewMtx.inverseTransposeTo(mtx); + GXLoadNrmMtxImm(mtx.m, 0); +} + +void LookAtCamera::loadOldMatrix() {} + +OrthoCamera::OrthoCamera() { + field_0x8C = 0.5f; + field_0x88 = 0.0f; + update_parms(); +} + +void OrthoCamera::update_parms() { + f32 z = field_0x8C; + f32 sin = Math::sin(field_0x88); + f32 cos = Math::cos(field_0x88); + mPosition.set(mRight.x, mRight.y, z); + mUp.set(sin, cos, 0.0f); +} + +void OrthoCamera::doUpdateMatrix() { + update_parms(); + LookAtCamera::doUpdateMatrix(); +} + +} // namespace EGG diff --git a/src/egg/gfx/eggLightTextureMgr.cpp b/src/egg/gfx/eggLightTextureMgr.cpp index 5aee8709..0f77697b 100644 --- a/src/egg/gfx/eggLightTextureMgr.cpp +++ b/src/egg/gfx/eggLightTextureMgr.cpp @@ -1,8 +1,11 @@ #include "egg/gfx/eggLightTextureMgr.h" #include "common.h" +#include "egg/gfx/eggG3DUtility.h" #include "egg/gfx/eggLightTexture.h" #include "egg/gfx/eggStateGX.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "rvl/GX/GXTexture.h" #include @@ -95,6 +98,28 @@ bool LightTextureManager::deleteTexture(int idx) { return false; } +int LightTextureManager::replaceModelTextures(nw4r::g3d::ResMdl mdl) const { + int count = 0; + for (u16 i = 0; i < mTextureCount; i++) { + count += replaceModelTexture(i, mdl); + } + return count; +} + +int LightTextureManager::replaceModelTexture(u16 tex, nw4r::g3d::ResMdl mdl) const { + if (mpTextures[tex] == nullptr) { + return 0; + } + GXTexObj obj; + mpTextures[tex]->getTexObj(&obj); + int count = 0; + for (u32 i = 0; i < mdl.GetResMatNumEntries(); i++) { + nw4r::g3d::ResMat mat = mdl.GetResMat(i); + // TODO + // count += G3DUtility::SetTexture(mat, nullptr, mpLightMgr[tex]->getName(), obj, false, void *param_6, int param_7, int param_8) + } +} + bool LightTextureManager::setBinaryToTexture(const void *data) { const LightTexture::Bin *bin = reinterpret_cast(data); for (int i = 0; i < getNumLightTextures(); i++) { From bd2c72d8c2b32b5568f75a51e9457d1bbdb6c613 Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 20 Mar 2025 16:42:31 +0100 Subject: [PATCH 16/62] Some PostEffect --- config/SOUE01/splits.txt | 6 ++ config/SOUE01/symbols.txt | 32 +++---- include/egg/gfx/eggCpuTexture.h | 3 +- include/egg/gfx/eggPostEffectBase.h | 4 +- include/egg/gfx/eggPostEffectBlur.h | 32 +++++-- include/egg/gfx/eggPostEffectUnk1.h | 27 +++++- src/egg/gfx/eggCamera.cpp | 2 + src/egg/gfx/eggCpuTexture.cpp | 76 ++++++++++++++++ src/egg/gfx/eggPostEffectBase.cpp | 4 +- src/egg/gfx/eggPostEffectBlur.cpp | 130 +++++++++++++++++++++++++++- src/egg/gfx/eggPostEffectMask.cpp | 2 +- src/egg/gfx/eggPostEffectUnk1.cpp | 93 +++++++++++++++++++- 12 files changed, 381 insertions(+), 30 deletions(-) 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 From 2c2d5849b4f64e5938ab7108d263ffad5d24962f Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 20 Mar 2025 19:46:28 +0100 Subject: [PATCH 17/62] 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 From a26b40083fa1113368f7e381836b87eba20e8c52 Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 20 Mar 2025 19:59:10 +0100 Subject: [PATCH 18/62] Simple match --- config/SOUE01/splits.txt | 2 ++ config/SOUE01/symbols.txt | 10 +++--- configure.py | 2 +- include/egg/gfx/eggPostEffectSimple.h | 18 +++++++++- src/egg/gfx/eggPostEffectSimple.cpp | 47 ++++++++++++++++++++++++++- 5 files changed, 71 insertions(+), 8 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index f491642c..1806fa0d 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2304,6 +2304,8 @@ egg/gfx/eggPostEffectMaskDOF.cpp: egg/gfx/eggPostEffectSimple.cpp: .text start:0x804B1BF0 end:0x804B1E58 + .data start:0x8056F210 end:0x8056F230 + .sdata2 start:0x8057F810 end:0x8057F818 egg/gfx/eggScreen.cpp: .text start:0x804B1E60 end:0x804B30B4 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index c6466bab..7eb1cd11 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26487,7 +26487,7 @@ scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x804A0E60; // type:function size:0 FUN_804a0ea0 = .text:0x804A0EA0; // type:function size:0x188 __dt__Q23EGG14PostEffectMaskFv = .text:0x804A1030; // type:function size:0x40 __dt__Q23EGG14PostEffectUnk1Fv = .text:0x804A1070; // type:function size:0x40 -FUN_804a10b0 = .text:0x804A10B0; // type:function size:0x40 +__dt__Q23EGG16PostEffectSimpleFv = .text:0x804A10B0; // type:function size:0x40 FUN_804a10f0 = .text:0x804A10F0; // type:function size:0x60 FUN_804a1150 = .text:0x804A1150; // type:function size:0x21C FUN_804a1370 = .text:0x804A1370; // type:function size:0x7A4 @@ -26720,8 +26720,8 @@ FUN_804b1570 = .text:0x804B1570; // type:function size:0x64C FUN_804b1bc0 = .text:0x804B1BC0; // type:function size:0x8 FUN_804b1bd0 = .text:0x804B1BD0; // type:function size:0x8 FUN_804b1be0 = .text:0x804B1BE0; // type:function size:0x8 -FUN_804b1bf0 = .text:0x804B1BF0; // type:function size:0x5C -FUN_804b1c50 = .text:0x804B1C50; // type:function size:0x208 +__ct__Q23EGG16PostEffectSimpleFv = .text:0x804B1BF0; // type:function size:0x5C +setMaterialInternal__Q23EGG16PostEffectSimpleFv = .text:0x804B1C50; // type:function size:0x208 Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen = .text:0x804B1E60; // type:function size:0x1DC __ct__Q23EGG6ScreenFv = .text:0x804B2040; // type:function size:0xCC __ct__Q23EGG6ScreenFffffPCQ23EGG6ScreenQ33EGG7Frustum10CanvasMode = .text:0x804B2110; // type:function size:0xBC @@ -37380,8 +37380,8 @@ __vt__Q23EGG14PostEffectBlur = .data:0x8056F170; // type:object size:0x1C __vt__Q23EGG14PostEffectUnk1 = .data:0x8056F190; // 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 +lbl_8056F1F0 = .data:0x8056F1F0; // type:object size:0x1C +__vt__Q23EGG16PostEffectSimple = .data:0x8056F210; // type:object size:0x1C sTVModeInfo__Q23EGG6Screen = .data:0x8056F230; // type:object size:0x24 data:2byte EGG__Screen__vtable = .data:0x8056F254; // type:object size:0x14 __vt__Q23EGG16ScreenEffectBase = .data:0x8056F268; // type:object size:0xC diff --git a/configure.py b/configure.py index 9e51b0f5..53e783db 100644 --- a/configure.py +++ b/configure.py @@ -895,7 +895,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggPostEffectUnk2.cpp"), # Unknown Object(Matching, "egg/gfx/eggPostEffectMask.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectMaskDOF.cpp"), - Object(NonMatching, "egg/gfx/eggPostEffectSimple.cpp"), + Object(Matching, "egg/gfx/eggPostEffectSimple.cpp"), Object(NonMatching, "egg/gfx/eggScreen.cpp"), Object(Matching, "egg/gfx/eggScreenEffectBase.cpp"), Object(NonMatching, "egg/gfx/eggScreenEffectBlur.cpp"), # Unknown Guess diff --git a/include/egg/gfx/eggPostEffectSimple.h b/include/egg/gfx/eggPostEffectSimple.h index c0053367..4de2455f 100644 --- a/include/egg/gfx/eggPostEffectSimple.h +++ b/include/egg/gfx/eggPostEffectSimple.h @@ -1,6 +1,22 @@ #ifndef EGG_POST_EFFECT_SIMPLE_H #define EGG_POST_EFFECT_SIMPLE_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggPostEffectBase.h" +#include "rvl/GX/GXTypes.h" +namespace EGG { + +class PostEffectSimple : public PostEffectBase { +public: + PostEffectSimple(); + virtual void setMaterialInternal() override; + +private: + /* 0x2C */ GXColor field_0x2C; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ GXTevScale field_0x34; + /* 0x38 */ s32 field_0x38; +}; + +} // namespace EGG #endif diff --git a/src/egg/gfx/eggPostEffectSimple.cpp b/src/egg/gfx/eggPostEffectSimple.cpp index 468e8539..24c18b9f 100644 --- a/src/egg/gfx/eggPostEffectSimple.cpp +++ b/src/egg/gfx/eggPostEffectSimple.cpp @@ -1,3 +1,48 @@ #include "egg/gfx/eggPostEffectSimple.h" -namespace EGG {} // namespace EGG +#include "egg/gfx/eggDrawGX.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +PostEffectSimple::PostEffectSimple() + : field_0x2C(DrawGX::WHITE), field_0x30(1.0f), field_0x34(GX_CS_SCALE_1), field_0x38(1) {} + +void PostEffectSimple::setMaterialInternal() { + loadTextureInternal(); + GXColor c = field_0x2C; + if (field_0x30 < 1.0f) { + scaleColor(c, c, true, field_0x30); + } + setMatColorChannel(); + GXSetNumTexGens(1); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x1e, 0, 0x7d); + nw4r::math::MTX34 mtx; + getBaseTexMtx(&mtx); + GXLoadTexMtxImm(mtx, 0x1e, GX_MTX_2x4); + setMatInd(); + GXSetNumTevStages(1); + GXSetTevDirect(GX_TEVSTAGE0); + 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); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevKColor(GX_KCOLOR0, c); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, mTexMapId, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, field_0x34, 1, GX_TEVPREV); + switch (field_0x38) { + case 0: GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); break; + case 1: GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_ZERO); break; + case 2: + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXA, GX_CC_KONST, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + break; + } + + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, field_0x34, true, GX_TEVPREV); + setMatPE(); +} + +} // namespace EGG From 70123b2777f85786fe94819068f6ac80e98cf6ef Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 20 Mar 2025 23:19:35 +0100 Subject: [PATCH 19/62] Some ScreenEffectBlur, CpuTexture --- config/SOUE01/splits.txt | 3 + config/SOUE01/symbols.txt | 36 +++---- include/egg/egg_types.h | 1 + include/egg/gfx/eggCpuTexture.h | 6 +- include/egg/gfx/eggFrustum.h | 4 + include/egg/gfx/eggGXUtility.h | 6 +- include/egg/gfx/eggPostEffectBase.h | 8 +- include/egg/gfx/eggPostEffectBlur.h | 15 ++- include/egg/gfx/eggScreenEffectBlur.h | 46 ++++++++- src/egg/gfx/eggCpuTexture.cpp | 134 +++++++++++++++++++++++++- src/egg/gfx/eggScreenEffectBlur.cpp | 111 ++++++++++++++++++++- 11 files changed, 338 insertions(+), 32 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 1806fa0d..8d54a2a5 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2189,6 +2189,7 @@ egg/gfx/eggCapTexture.cpp: egg/gfx/eggCpuTexture.cpp: .text start:0x8049DA30 end:0x8049EC94 .data start:0x8056ED80 end:0x8056EDA0 + .sdata2 start:0x8057F418 end:0x8057F440 egg/gfx/eggDrawGX.cpp: .text start:0x8049ECA0 end:0x804A0C24 @@ -2319,6 +2320,8 @@ egg/gfx/eggScreenEffectBase.cpp: egg/gfx/eggScreenEffectBlur.cpp: .text start:0x804B30F0 end:0x804B3D98 + .data start:0x8056F278 end:0x8056F2B0 + .sdata2 start:0x8057F840 end:0x8057F868 egg/gfx/eggStateEfb.cpp: .text start:0x804B3DA0 end:0x804B460C diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 7eb1cd11..85c66915 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26431,8 +26431,8 @@ FUN_8049d780 = .text:0x8049D780; // type:function size:0x40 configure__Q23EGG10CapTextureFv = .text:0x8049D7C0; // type:function size:0x7C capture__Q23EGG10CapTextureFUsUsbi = .text:0x8049D840; // type:function size:0x184 FUN_8049d9d0 = .text:0x8049D9D0; // type:function size:0x58 -calcColorGradient_EGG_CpuTexture_8049da30 = .text:0x8049DA30; // type:function size:0x188 -makeGradient_EGG_CpuTexture_8049dbc0 = .text:0x8049DBC0; // type:function size:0x450 +calcColorGradient__Q23EGG27@unnamed@eggCpuTexture_cpp@FR8_GXColorRC8_GXColorRC8_GXColorf = .text:0x8049DA30; // type:function size:0x188 +makeGradient__Q23EGG27@unnamed@eggCpuTexture_cpp@FiP8_GXColoriiiRC8_GXColorRC8_GXColor = .text:0x8049DBC0; // type:function size:0x450 __ct__Q23EGG10CpuTextureFv = .text:0x8049E010; // type:function size:0x44 __ct__Q23EGG10CpuTextureFUsUs9_GXTexFmt = .text:0x8049E060; // type:function size:0x40 __ct__Q23EGG10CpuTextureFPC9_GXTexObj = .text:0x8049E0A0; // type:function size:0xB0 @@ -26443,8 +26443,8 @@ load__Q23EGG10CpuTextureCF11_GXTexMapID = .text:0x8049E1F0; // type:function siz getTexObj__Q23EGG10CpuTextureCFP9_GXTexObj = .text:0x8049E230; // type:function size:0x80 flush__Q23EGG10CpuTextureCFv = .text:0x8049E2B0; // type:function size:0x4C buildHeader__Q23EGG10CpuTextureCFv = .text:0x8049E300; // type:function size:0x84 -fillNormalMapSphere__EGG_CpuTexture_8049e390 = .text:0x8049E390; // type:function size:0x1BC -fillGradient_EGG_CpuTexture_8049e550 = .text:0x8049E550; // type:function size:0x3A8 +fillNormalMapSphere__Q23EGG10CpuTextureFff = .text:0x8049E390; // type:function size:0x1BC +fillGradient__Q23EGG10CpuTextureFiiUsUsRC8_GXColorRC8_GXColorbb = .text:0x8049E550; // type:function size:0x3A8 alloc__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049E900; // type:function size:0x84 allocWithHeaderDebug__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049E990; // type:function size:0xA8 allocate__Q23EGG10CpuTextureFPQ23EGG4Heap = .text:0x8049EA40; // type:function size:0x4 @@ -26579,7 +26579,7 @@ getTexMtxID__Q23EGG9GXUtilityFi = .text:0x804A7820; // type:function size:0xC setScaleOffsetPerspective__Q23EGG9GXUtilityFPfffff = .text:0x804A7830; // type:function size:0x40 getTexObj__Q23EGG9GXUtilityFP9_GXTexObjRCQ23EGG7ResTIMG = .text:0x804A7870; // type:function size:0x100 getTexObj__Q23EGG9GXUtilityFP9_GXTexObjQ34nw4r3g3d6ResTex14_GXTexWrapMode14_GXTexWrapMode12_GXTexFilter12_GXTexFilter = .text:0x804A7970; // type:function size:0xB8 -FUN_804a7a30 = .text:0x804A7A30; // type:function size:0x190 +getNormalColor__Q23EGG9GXUtilityFR8_GXColorRCQ23EGG8Vector3f = .text:0x804A7A30; // type:function size:0x190 __dt__Q23EGG8IScnProcFv = .text:0x804A7BC0; // type:function size:0xB8 createScnProc__Q23EGG8IScnProcFUsP12MEMAllocator = .text:0x804A7C80; // type:function size:0x110 setPriorityScnProc__Q23EGG8IScnProcFUsUcb = .text:0x804A7D90; // type:function size:0xBC @@ -26744,18 +26744,18 @@ FUN_804b2ee0 = .text:0x804B2EE0; // type:function size:0x14C __sinit_\eggScreen_cpp = .text:0x804B3030; // type:function size:0x84 scope:local __ct__Q23EGG16ScreenEffectBaseFv = .text:0x804B30C0; // type:function size:0x18 __sinit_\eggScreenEffectBase_cpp = .text:0x804B30E0; // type:function size:0xC scope:local -FUN_804b30f0 = .text:0x804B30F0; // type:function size:0x104 -FUN_804b3200 = .text:0x804B3200; // type:function size:0xA8 -FUN_804b32b0 = .text:0x804B32B0; // type:function size:0x454 -FUN_804b3710 = .text:0x804B3710; // type:function size:0x184 -FUN_804b38a0 = .text:0x804B38A0; // type:function size:0x78 -FUN_804b3920 = .text:0x804B3920; // type:function size:0x6C -FUN_804b3990 = .text:0x804B3990; // type:function size:0x3B4 -FUN_804b3d50 = .text:0x804B3D50; // type:function size:0x8 -FUN_804b3d60 = .text:0x804B3D60; // type:function size:0x8 -FUN_804b3d70 = .text:0x804B3D70; // type:function size:0x8 -FUN_804b3d80 = .text:0x804B3D80; // type:function size:0x8 -FUN_804b3d90 = .text:0x804B3D90; // type:function size:0x8 +__ct__Q23EGG16ScreenEffectBlurFv = .text:0x804B30F0; // type:function size:0x104 +__dt__Q23EGG16ScreenEffectBlurFv = .text:0x804B3200; // type:function size:0xA8 +fn_804B32B0__Q23EGG16ScreenEffectBlurFv = .text:0x804B32B0; // type:function size:0x454 +fn_804B3710__Q23EGG16ScreenEffectBlurFv = .text:0x804B3710; // type:function size:0x184 +SetBinaryInner__Q23EGG16ScreenEffectBlurFRCQ33EGG33IBinary3Bin = .text:0x804B38A0; // type:function size:0x78 +GetBinaryInner__Q23EGG16ScreenEffectBlurCFPQ33EGG33IBinary3Bin = .text:0x804B3920; // type:function size:0x6C +SetBinaryInner__Q23EGG16ScreenEffectBlurFRCQ33EGG33IBinary3BinRCQ33EGG33IBinary3Binf = .text:0x804B3990; // type:function size:0x3B4 +GetBinarySize__Q23EGG33IBinaryCFv = .text:0x804B3D50; // type:function size:0x8 +@8@SetBinaryInner__Q23EGG16ScreenEffectBlurFRCQ33EGG33IBinary3Bin = .text:0x804B3D60; // type:function size:0x8 +@8@SetBinaryInner__Q23EGG16ScreenEffectBlurFRCQ33EGG33IBinary3BinRCQ33EGG33IBinary3Binf = .text:0x804B3D70; // type:function size:0x8 +@8@GetBinaryInner__Q23EGG16ScreenEffectBlurCFPQ33EGG33IBinary3Bin = .text:0x804B3D80; // type:function size:0x8 +@8@__dt__Q23EGG16ScreenEffectBlurFv = .text:0x804B3D90; // type:function size:0x8 Clean__Q23EGG8StateEfbFv = .text:0x804B3DA0; // type:function size:0x78 captureEfb__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypebUl = .text:0x804B3E20; // type:function size:0x3C8 releaseEfb__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypeUl = .text:0x804B41F0; // type:function size:0x7C @@ -37385,7 +37385,7 @@ __vt__Q23EGG16PostEffectSimple = .data:0x8056F210; // type:object size:0x1C sTVModeInfo__Q23EGG6Screen = .data:0x8056F230; // type:object size:0x24 data:2byte EGG__Screen__vtable = .data:0x8056F254; // type:object size:0x14 __vt__Q23EGG16ScreenEffectBase = .data:0x8056F268; // type:object size:0xC -lbl_8056F278 = .data:0x8056F278; // type:object size:0x38 +__vt__Q23EGG16ScreenEffectBlur = .data:0x8056F278; // type:object size:0x38 __vt__Q23EGG13TextureBuffer = .data:0x8056F2B0; // type:object size:0x10 __vt__Q23EGG9ArcPlayer = .data:0x8056F2C0; // type:object size:0x5C __vt__Q23EGG14SimpleAudioMgr = .data:0x8056F320; // type:object size:0xA4 diff --git a/include/egg/egg_types.h b/include/egg/egg_types.h index c1ff24f8..f3f96c61 100644 --- a/include/egg/egg_types.h +++ b/include/egg/egg_types.h @@ -37,6 +37,7 @@ class PostEffectBlur; class PostEffectBlurGather; class PostEffectHDR; class PostEffectSimple; +class PostEffectUnk2; class ResTIMG; class ScnRenderer; class ScnRootEx; diff --git a/include/egg/gfx/eggCpuTexture.h b/include/egg/gfx/eggCpuTexture.h index 7269471f..5c2e55cb 100644 --- a/include/egg/gfx/eggCpuTexture.h +++ b/include/egg/gfx/eggCpuTexture.h @@ -9,7 +9,6 @@ namespace EGG { class CpuTexture { - void makeGradient(UNKTYPE); public: struct Header { @@ -62,11 +61,10 @@ public: u32 getTexBufferSize() const; void buildHeader() const; Header *initHeader(); + void fillNormalMapSphere(f32, f32); void fillGradient(int op, int, u16, u16, const GXColor&, const GXColor&, bool, bool); - UNKTYPE func_80086C8C(UNKTYPE); - void allocTexBuffer(); - void allocTexBufferAndHeader(); + void setColor(u16 x, u16 y, GXColor color); GXColor getColor(u16 x, u16 y) const; diff --git a/include/egg/gfx/eggFrustum.h b/include/egg/gfx/eggFrustum.h index 01c93063..f3dd56d3 100644 --- a/include/egg/gfx/eggFrustum.h +++ b/include/egg/gfx/eggFrustum.h @@ -83,6 +83,10 @@ public: void SetOffset(const nw4r::math::VEC2 &offset) { mOffset = offset; } + + const nw4r::math::VEC2 &GetSize() { + return mSize; + } }; } // namespace EGG diff --git a/include/egg/gfx/eggGXUtility.h b/include/egg/gfx/eggGXUtility.h index daf49239..d3ac74b7 100644 --- a/include/egg/gfx/eggGXUtility.h +++ b/include/egg/gfx/eggGXUtility.h @@ -2,8 +2,10 @@ #define EGG_GX_UTILITY_H #include "egg/gfx/eggTexture.h" +#include "egg/math/eggVector.h" #include "nw4r/g3d/res/g3d_restex.h" #include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" namespace EGG { @@ -11,7 +13,9 @@ 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); + static void getTexObj(GXTexObj *, nw4r::g3d::ResTex, GXTexWrapMode, GXTexWrapMode, GXTexFilter, GXTexFilter); + + static void getNormalColor(GXColor &outColor, const Vector3f &vec); }; } // namespace EGG diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index 2c3207ed..84a533c9 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -9,6 +9,13 @@ namespace EGG { class PostEffectBase { +public: + void setField_0x00(u32 val) { + field_0x00 = val; + } + + static void setProjection(const EGG::Screen &screen); + protected: u32 field_0x00; // at 0x0 CapTexture *mpCapTexture; // at 0x4 @@ -34,7 +41,6 @@ protected: 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); protected: virtual void draw(f32 width, f32 height); // at 0xC diff --git a/include/egg/gfx/eggPostEffectBlur.h b/include/egg/gfx/eggPostEffectBlur.h index 62b6625e..103a55af 100644 --- a/include/egg/gfx/eggPostEffectBlur.h +++ b/include/egg/gfx/eggPostEffectBlur.h @@ -4,10 +4,11 @@ #include "common.h" #include "egg/egg_types.h" #include "egg/gfx/eggPostEffectBase.h" +#include "rvl/GX/GXTypes.h" namespace EGG { -class PostEffectBlur : PostEffectBase { +class PostEffectBlur : public PostEffectBase { struct Stage { /* 0x00 */ u8 field_0x00; /* 0x01 */ GXColor field_0x01; @@ -32,6 +33,18 @@ public: field_0x30 = val; } + void setStage0Field0(u8 u1) { + field_0x38[0].field_0x00 = u1; + } + + void setStage0Color(GXColor clr) { + field_0x38[0].field_0x01 = clr; + } + + void setStage0F(f32 f) { + field_0x38[0].field_0x0C = f; + } + private: void drawInternal(u8, u8, f32, f32); diff --git a/include/egg/gfx/eggScreenEffectBlur.h b/include/egg/gfx/eggScreenEffectBlur.h index 0553161f..86150ff8 100644 --- a/include/egg/gfx/eggScreenEffectBlur.h +++ b/include/egg/gfx/eggScreenEffectBlur.h @@ -2,15 +2,55 @@ #define EGG_SCREEN_EFFECT_BLUR_H #include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggScreenEffectBase.h" +#include "egg/prim/eggBinary.h" +#include "rvl/GX/GXTypes.h" + namespace EGG { -class ScreenEffectBlur { +class ScreenEffectBlur : public ScreenEffectBase, IBinary { public: + struct BinData { + u8 field_0x00; + u8 field_0x01; + u8 field_0x02; + f32 field_0x04; + f32 field_0x08; + f32 field_0x0C; + f32 field_0x10; + f32 field_0x14; + f32 field_0x18; + u8 field_0x1C; + u8 field_0x1D; + u8 field_0x1E; + u8 field_0x1F; + }; + ScreenEffectBlur(); - ~ScreenEffectBlur(); + virtual ~ScreenEffectBlur(); + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + + void fn_804B32B0(); + void fn_804B3710(); private: - u8 _0x00[0x38 - 0x00]; + /* 0x0C */ u8 field_0x0C; + /* 0x0D */ u8 field_0x0D; + /* 0x0E */ u8 field_0x0E; + /* 0x10 */ f32 field_0x10; + /* 0x14 */ f32 field_0x14; + /* 0x18 */ f32 field_0x18; + /* 0x1C */ f32 field_0x1C; + /* 0x20 */ f32 field_0x20; + /* 0x24 */ f32 field_0x24; + /* 0x28 */ GXColor field_0x28; + /* 0x2C */ PostEffectUnk2 *mpUnk2; + /* 0x30 */ PostEffectBlur *mpBlur; + /* 0x34 */ TextureBuffer *mpCpuTexture; }; } // namespace EGG diff --git a/src/egg/gfx/eggCpuTexture.cpp b/src/egg/gfx/eggCpuTexture.cpp index 9052ff8b..fc927b2f 100644 --- a/src/egg/gfx/eggCpuTexture.cpp +++ b/src/egg/gfx/eggCpuTexture.cpp @@ -2,12 +2,74 @@ #include "common.h" #include "egg/core/eggHeap.h" +#include "egg/gfx/eggGXUtility.h" +#include "egg/math/eggVector.h" #include "rvl/GX/GXTexture.h" #include "rvl/GX/GXTypes.h" +#include "rvl/MTX/vec.h" #include "rvl/OS/OSCache.h" namespace EGG { +namespace { + +void calcColorGradient(GXColor &outColor, const GXColor &c1, const GXColor &c2, f32 amount) { + if (amount <= 0.0f) { + outColor = c1; + } else if (amount >= 1.0f) { + outColor = c2; + } else { + outColor.r = c1.r + amount * (c2.r - c1.r); + outColor.g = c1.g + amount * (c2.g - c1.g); + outColor.b = c1.b + amount * (c2.b - c1.b); + outColor.a = c1.a + amount * (c2.a - c1.a); + } +} + +void makeGradient(int op, GXColor *outColor, int size, int start, int end, const GXColor &c1, const GXColor &c2) { + int start_p1 = start + 1; + // Weird instruction calculation + for (int i = 0; i < start_p1; i++) { + outColor[i] = c1; + } + + int end_1 = end - 1; + for (int i = end_1; i < size; i++) { + outColor[i] = c2; + } + + for (int i = start_p1; i < end_1; i++) { + f32 ratio = (f32)(i - start) / (f32)(end - start); + switch (op) { + case 0: break; + case 1: ratio *= ratio; break; + case 2: + ratio *= ratio; + ratio *= ratio; + break; + case 3: + ratio *= ratio; + ratio *= ratio; + ratio *= ratio; + break; + case 4: + ratio *= ratio; + ratio *= ratio; + ratio *= ratio; + ratio *= ratio; + break; + case 5: ratio = -(ratio - 1.0f) * (ratio - 1.0f) + 1.0f; break; + case 6: + ratio -= 1.0f; + ratio = -ratio * ratio * ratio * ratio + 1.0f; + break; + } + calcColorGradient(outColor[i], c1, c2, ratio); + } +} + +} // namespace + CpuTexture::CpuTexture() { mWidth = 0; mHeight = 0; @@ -196,11 +258,10 @@ GXColor CpuTexture::getColor(u16 x, u16 y) const { 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]; + c.g = c.b; + c.r = c.b; break; } default: break; @@ -208,4 +269,71 @@ GXColor CpuTexture::getColor(u16 x, u16 y) const { return c; } +extern "C" double sqrt(double); + +void CpuTexture::fillNormalMapSphere(f32 f1, f32 f2) { + // NONMATCHING + // fpr regswaps + f32 mid = static_cast(mWidth / 2); + for (u16 y = 0; y < mHeight; y++) { + for (u16 x = 0; x < mWidth; x++) { + Vector3f vec; + vec.x = f1 * ((x + f2) - mid); + vec.y = f1 * -((y + f2) - mid); + f32 z = mid * mid - (vec.x * vec.x + vec.y * vec.y); + vec.z = z < 0.0f ? 0.0f : (f32)sqrt(z); + PSVECNormalize(vec, vec); + GXColor c; + GXUtility::getNormalColor(c, vec); + c.r = c.a; + setColor(x, y, c); + } + } + flush(); +} + +void CpuTexture::fillGradient( + int op, int unk, u16 start, u16 end, const GXColor &c1, const GXColor &c2, bool b1, bool b2 +) { + GXColor gradient[1024]; + GXColor colors[256]; + + + // NONMATCHING - regswaps + bool swapMode = unk == 0x73 || unk == 0x53; + + u16 width = swapMode ? mWidth : mHeight; + int size = width; + u16 height = swapMode ? mHeight : mWidth; + int mid = width / 2; + makeGradient(op, gradient, size, start, end, c1, c2); + if (b1) { + int i2 = mid; + for (int i = 0; i < size; i++, i2++) { + colors[i].r = gradient[i < mid ? i2 : i - mid].r; + colors[i].g = gradient[i < mid ? i2 : i - mid].g; + colors[i].b = gradient[i < mid ? i2 : i - mid].b; + colors[i].a = gradient[i < mid ? i2 : i - mid].a; + } + + for (int i = 0; i < size; i++) { + gradient[i] = colors[i]; + } + } + + u16 start2 = b2 ? 0 : start; + u16 end2 = b2 ? size : end; + + for (u16 x = start2; x < end2; x++) { + for (u16 y = 0; y < height; y++) { + if (swapMode) { + setColor(x, y, gradient[x & 0xFFFF]); + } else { + setColor(y, x, gradient[x & 0xFFFF]); + } + } + } + flush(); +} + } // namespace EGG diff --git a/src/egg/gfx/eggScreenEffectBlur.cpp b/src/egg/gfx/eggScreenEffectBlur.cpp index 65a45952..c445b216 100644 --- a/src/egg/gfx/eggScreenEffectBlur.cpp +++ b/src/egg/gfx/eggScreenEffectBlur.cpp @@ -1,3 +1,112 @@ #include "egg/gfx/eggScreenEffectBlur.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "egg/gfx/eggPostEffectBlur.h" // IWYU pragma: keep +#include "egg/gfx/eggPostEffectUnk2.h" // IWYU pragma: keep +#include "egg/gfx/eggStateGX.h" +#include "egg/gfx/eggTextureBuffer.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +static const GXColor sDefaultColor = {0, 0, 0, 0xFF}; +static const GXColor sDefaultColor2 = {0x80, 0x80, 0x80, 0x80}; + +ScreenEffectBlur::ScreenEffectBlur() + : field_0x0C(3), + field_0x0D(0), + field_0x0E(0), + field_0x10(1.0f), + field_0x14(1.0f), + field_0x18(0.5f), + field_0x1C(1.0f), + field_0x20(0.5f), + field_0x24(0.0f), + field_0x28(sDefaultColor), + mpCpuTexture(0) { + mpUnk2 = new PostEffectUnk2(); + mpBlur = new PostEffectBlur(); + mpBlur->setField_0x00(2); + mpBlur->setStage0Field0(4); + mpBlur->setStage0Color(sDefaultColor2); + mpBlur->setStage0F(field_0x1C); +} + +ScreenEffectBlur::~ScreenEffectBlur() { + delete mpUnk2; + delete mpBlur; +} + +void ScreenEffectBlur::fn_804B32B0() { + // Oh god +} + +void ScreenEffectBlur::fn_804B3710() { + if ((mFlag & 1) != 0) { + StateGX::invalidateTexAllGX(); + PostEffectBase::setProjection(sScreen); + nw4r::math::MTX34 mtx; + // Have to perform a float -> u16 -> float round trip here... + u16 sizeY = sScreen.GetSize().y; + u16 sizeX = sScreen.GetSize().x; + PSMTXScale(mtx, sizeX, sizeY, 0.0f); + mpCpuTexture->load(GX_TEXMAP0); + DrawGX::BeginDrawScreen(true, true, true); + GXSetTevKColor(GX_KCOLOR0, field_0x28); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_KONST); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_KONST, GX_CA_TEXA, GX_CA_ZERO); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_GREATER, field_0x0D); + DrawGX::SetBlendMode((field_0x0C & 4) != 0 ? DrawGX::BLEND_14 : DrawGX::BLEND_0); + DrawGX::DrawDL(DrawGX::DL_16, mtx, DrawGX::WHITE); + } + if (mpCpuTexture != nullptr) { + mpCpuTexture->free(); + mpCpuTexture = nullptr; + } +} + +void ScreenEffectBlur::SetBinaryInner(const Bin &bin) { + if (bin.mHeader.mVersion != 0) { + return; + } + field_0x0C = bin.mData.field_0x00; + field_0x0D = bin.mData.field_0x01; + field_0x0E = bin.mData.field_0x02; + field_0x10 = bin.mData.field_0x04; + field_0x14 = bin.mData.field_0x08; + field_0x18 = bin.mData.field_0x0C; + field_0x1C = bin.mData.field_0x10; + field_0x20 = bin.mData.field_0x14; + field_0x24 = bin.mData.field_0x18; + field_0x28.r = bin.mData.field_0x1C; + field_0x28.g = bin.mData.field_0x1D; + field_0x28.b = bin.mData.field_0x1E; + field_0x28.a = bin.mData.field_0x1F; +} + +void ScreenEffectBlur::GetBinaryInner(Bin *bin) const { + bin->mData.field_0x00 = field_0x0C; + bin->mData.field_0x01 = field_0x0D; + bin->mData.field_0x02 = field_0x0E; + bin->mData.field_0x04 = field_0x10; + bin->mData.field_0x08 = field_0x14; + bin->mData.field_0x0C = field_0x18; + bin->mData.field_0x10 = field_0x1C; + bin->mData.field_0x14 = field_0x20; + bin->mData.field_0x18 = field_0x24; + bin->mData.field_0x1C = field_0x28.r; + bin->mData.field_0x1D = field_0x28.g; + bin->mData.field_0x1E = field_0x28.b; + bin->mData.field_0x1F = field_0x28.a; +} + +void ScreenEffectBlur::SetBinaryInner(const Bin &bin1, const Bin &bin2, f32 blend) {} + +} // namespace EGG From 4890acfe80ce5d1b723febfbb0d2a7a1395cc809 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 21 Mar 2025 00:46:41 +0100 Subject: [PATCH 20/62] Some frustum/screen --- config/SOUE01/splits.txt | 7 + config/SOUE01/symbols.txt | 22 +- include/egg/gfx/eggFrustum.h | 142 +++++++++---- include/egg/gfx/eggGXUtility.h | 1 + include/egg/gfx/eggGfxEngine.h | 8 +- include/egg/gfx/eggScreen.h | 84 +++++--- include/egg/gfx/eggStateGX.h | 10 +- src/d/lyt/d2d.cpp | 6 +- src/egg/gfx/eggFrustum.cpp | 239 ++++++++++++++++++++- src/egg/gfx/eggPostEffectBase.cpp | 2 +- src/egg/gfx/eggScreen.cpp | 342 +++++++++++++++++++++++++++++- src/m/m2d.cpp | 6 +- 12 files changed, 773 insertions(+), 96 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 8d54a2a5..c6b4d2ec 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2228,6 +2228,9 @@ egg/gfx/eggFogManager.cpp: egg/gfx/eggFrustum.cpp: .text start:0x804A5F60 end:0x804A6854 .ctors start:0x804DB99C end:0x804DB9A0 + .data start:0x8056F030 end:0x8056F048 + .sbss start:0x80576810 end:0x80576820 + .sdata2 start:0x8057F618 end:0x8057F63C egg/gfx/eggG3DUtility.cpp: .text start:0x804A6860 end:0x804A75B0 @@ -2311,6 +2314,10 @@ egg/gfx/eggPostEffectSimple.cpp: egg/gfx/eggScreen.cpp: .text start:0x804B1E60 end:0x804B30B4 .ctors start:0x804DB9A8 end:0x804DB9AC + .data start:0x8056F230 end:0x8056F268 + .sbss start:0x80576870 end:0x80576898 + .sdata2 start:0x8057F818 end:0x8057F840 + .bss start:0x80674F00 end:0x80674F88 egg/gfx/eggScreenEffectBase.cpp: .text start:0x804B30C0 end:0x804B30EC diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 85c66915..1a95fda0 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26545,7 +26545,7 @@ __ct__Q23EGG7FrustumFQ33EGG7Frustum14ProjectionTypeRCQ34nw4r4math4VEC2ffQ33EGG7F __ct__Q23EGG7FrustumFRCQ23EGG7Frustum = .text:0x804A5FD0; // type:function size:0x3C ResetOrthographic__Q23EGG7FrustumFffffff = .text:0x804A6010; // type:function size:0x104 CopyFromAnother__Q23EGG7FrustumFRCQ23EGG7Frustum = .text:0x804A6120; // type:function size:0x74 -SetFovy__Q23EGG7FrustumFf = .text:0x804A61A0; // type:function size:0x68 +SetFovy__Q23EGG7FrustumFd = .text:0x804A61A0; // type:function size:0x68 ConvertToCanvasLU__Q23EGG7FrustumCFffPfPf = .text:0x804A6210; // type:function size:0x4C GetScreenSizeToViewSize__Q23EGG7FrustumCFff = .text:0x804A6260; // type:function size:0x30 SetProjectionGX__Q23EGG7FrustumCFv = .text:0x804A6290; // type:function size:0x14 @@ -26731,7 +26731,7 @@ CopyToG3D__Q23EGG6ScreenCFQ34nw4r3g3d6Camera = .text:0x804B2390; // type:functio CopyFromAnother__Q23EGG6ScreenFRCQ23EGG6Screen = .text:0x804B24C0; // type:function size:0xD0 Reset__Q23EGG6ScreenFffffQ33EGG7Frustum10CanvasMode = .text:0x804B2590; // type:function size:0x38 SetParent__Q23EGG6ScreenFPCQ23EGG6Screen = .text:0x804B25D0; // type:function size:0x30 -FUN_804b2600 = .text:0x804B2600; // type:function size:0x24 +SetUnkFlag8__Q23EGG6ScreenFv = .text:0x804B2600; // type:function size:0x24 OnDirectEfb__Q23EGG6ScreenFv = .text:0x804B2630; // type:function size:0x4D8 GetDataEfb__Q23EGG6ScreenCFv = .text:0x804B2B10; // type:function size:0x5C IsChangeEfb__Q23EGG6ScreenCFv = .text:0x804B2B70; // type:function size:0x2C @@ -29879,7 +29879,7 @@ __vt__Q23d3d12UnkWithWater = .data:0x805009C0; // type:object size:0x10 __vt__Q23d3d14AnmMdlWrapper2 = .data:0x805009D0; // type:object size:0x50 __vt__Q23d3d13AnmMdlWrapper = .data:0x80500A20; // type:object size:0x50 lbl_80500A70 = .data:0x80500A70; // type:object size:0x2C -lbl_80500A9C = .data:0x80500A9C; // type:object size:0xC +lbl_80500A9C = .data:0x80500A9C; // type:object size:0xB data:string lbl_80500AA8 = .data:0x80500AA8; // type:object size:0x10 data:string __vt__14dScnCallback_c = .data:0x80500AB8; // type:object size:0x20 lbl_80500AD8 = .data:0x80500AD8; // type:object size:0x18 @@ -37366,7 +37366,7 @@ __vt__Q23EGG11DrawPathDOF = .data:0x8056EF28; // type:object size:0x78 lbl_8056EFA0 = .data:0x8056EFA0; // type:object size:0x50 __vt__Q23EGG3Fog = .data:0x8056EFF0; // type:object size:0x20 __vt__Q23EGG10FogManager = .data:0x8056F010; // type:object size:0x1C -EGG__Frustum__vtable = .data:0x8056F030; // type:object size:0x18 +__vt__Q23EGG7Frustum = .data:0x8056F030; // type:object size:0x14 EGG__GfxEnginer__Configuration__vtable = .data:0x8056F048; // type:object size:0x10 __vt__Q23EGG8IScnProc = .data:0x8056F058; // type:object size:0x10 EGG__LightManager__vtable = .data:0x8056F068; // type:object size:0x30 @@ -37383,7 +37383,7 @@ __vt__Q23EGG14PostEffectMask = .data:0x8056F1D0; // type:object size:0x1C lbl_8056F1F0 = .data:0x8056F1F0; // type:object size:0x1C __vt__Q23EGG16PostEffectSimple = .data:0x8056F210; // type:object size:0x1C sTVModeInfo__Q23EGG6Screen = .data:0x8056F230; // type:object size:0x24 data:2byte -EGG__Screen__vtable = .data:0x8056F254; // type:object size:0x14 +__vt__Q23EGG6Screen = .data:0x8056F254; // type:object size:0x14 __vt__Q23EGG16ScreenEffectBase = .data:0x8056F268; // type:object size:0xC __vt__Q23EGG16ScreenEffectBlur = .data:0x8056F278; // type:object size:0x38 __vt__Q23EGG13TextureBuffer = .data:0x8056F2B0; // type:object size:0x10 @@ -41149,8 +41149,8 @@ sInstantHalt__Q23EGG6Assert = .sbss:0x80576804; // type:object size:0x1 data:byt sAssertOccurred__Q23EGG6Assert = .sbss:0x80576805; // type:object size:0x1 data:byte s_flag__Q23EGG6DrawGX = .sbss:0x80576808; // 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 +sGlobalScale__Q23EGG7Frustum = .sbss:0x80576810; // type:object size:0x8 data:float +sGlobalOffset__Q23EGG7Frustum = .sbss:0x80576818; // type:object size:0x8 data:float lbl_80576820 = .sbss:0x80576820; // type:object size:0x1 data:byte sAllocator__Q23EGG10G3DUtility = .sbss:0x80576824; // type:object size:0x4 data:4byte lbl_80576828 = .sbss:0x80576828; // type:object size:0x4 data:4byte @@ -41173,15 +41173,15 @@ lbl_80576860 = .sbss:0x80576860; // type:object size:0x1 data:byte lbl_80576861 = .sbss:0x80576861; // type:object size:0x7 data:byte lbl_80576868 = .sbss:0x80576868; // type:object size:0x8 data:float sTVMode__Q23EGG6Screen = .sbss:0x80576870; // type:object size:0x4 data:4byte -lbl_80576874 = .sbss:0x80576874; // type:object size:0x4 data:4byte +spRoot__Q23EGG6Screen = .sbss:0x80576874; // type:object size:0x4 data:4byte lbl_80576878 = .sbss:0x80576878; // type:object size:0x4 data:4byte lbl_8057687C = .sbss:0x8057687C; // type:object size:0x4 data:4byte lbl_80576880 = .sbss:0x80576880; // type:object size:0x4 data:float lbl_80576888 = .sbss:0x80576888; // type:object size:0x4 data:float lbl_80576890 = .sbss:0x80576890; // type:object size:0x8 data:byte lbl_80576898 = .sbss:0x80576898; // type:object size:0x8 data:4byte -lbl_805768A0 = .sbss:0x805768A0; // type:object size:0x2 data:2byte -lbl_805768A2 = .sbss:0x805768A2; // type:object size:0x2 data:2byte +s_widthEfb__Q23EGG7StateGX = .sbss:0x805768A0; // type:object size:0x2 data:2byte +s_heightEfb__Q23EGG7StateGX = .sbss:0x805768A2; // type:object size:0x2 data:2byte lbl_805768A4 = .sbss:0x805768A4; // type:object size:0x4 data:4byte lbl_805768A8 = .sbss:0x805768A8; // type:object size:0x4 data:4byte sDefaultTexColor__Q23EGG7StateGX = .sbss:0x805768AC; // type:object size:0x1 data:byte @@ -49804,7 +49804,7 @@ 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 lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0xC data:float -lbl_80674F00 = .bss:0x80674F00; // type:object size:0x88 data:4byte +@LOCAL@Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen@defaultRoot = .bss:0x80674F00; // type:object size:0x88 data:4byte sScreen__Q23EGG16ScreenEffectBase = .bss:0x80674F88; // type:object size:0x88 lbl_80675010 = .bss:0x80675010; // type:object size:0x30 lbl_80675040 = .bss:0x80675040; // type:object size:0x18 data:float diff --git a/include/egg/gfx/eggFrustum.h b/include/egg/gfx/eggFrustum.h index f3dd56d3..5adbc40e 100644 --- a/include/egg/gfx/eggFrustum.h +++ b/include/egg/gfx/eggFrustum.h @@ -1,52 +1,54 @@ #ifndef EGG_FRUSTUM_H #define EGG_FRUSTUM_H -#include "common.h" #include "nw4r/g3d/g3d_camera.h" namespace EGG { - -// TODO: Fill out more class Frustum { public: - enum CanvasMode { - CANVAS_0, - CANVAS_1, + enum Flag { + FLAG_DIRTY = (1 << 0), + FLAG_0x40 = (1 << 6), }; + enum ProjectionType { PROJ_ORTHO, PROJ_PERSP }; - enum Flag { - FLAG_DIRTY = (1 << 0), - FLAG_0x40 = 0x40, + enum CanvasMode { + CANVASMODE_0, + CANVASMODE_1, }; -private: - /* 0x00 */ ProjectionType mProjType; - /* 0x04 */ CanvasMode mCanvasMode; - /* 0x08 */ nw4r::math::VEC2 mSize; - /* 0x10 */ f32 mFovY; - /* 0x14 */ f32 mTanFovY; - /* 0x18 */ f32 mNearZ; - /* 0x1C */ f32 mFarZ; - /* 0x20 */ nw4r::math::VEC2 mOffset; - /* 0x28 */ nw4r::math::VEC3 mScale; - /* 0x34 */ mutable u16 mFlags; +protected: + ProjectionType mProjType; // at 0x0 + CanvasMode mCanvasMode; // at 0x4 + nw4r::math::VEC2 mSize; // at 0x8 + f32 mFovY; // at 0x10 + f32 mTanFovY; // at 0x14 + f32 mNearZ; // at 0x18 + f32 mFarZ; // at 0x1C + nw4r::math::VEC2 mOffset; // at 0x20 + nw4r::math::VEC3 mScale; // at 0x28 + mutable u16 mFlags; // at 0x34 public: - // vt at 0x38 - virtual ~Frustum() {} - virtual void SetProjectionGX() const; - virtual void CopyToG3D(nw4r::g3d::Camera) const; + Frustum(ProjectionType, const nw4r::math::VEC2 &, f32, f32, CanvasMode); + Frustum(const Frustum &); - ProjectionType GetProjectionType() const { - return mProjType; - } - void SetProjectionType(ProjectionType type) { - mProjType = type; - } + virtual ~Frustum() {} // at 0x8 + virtual void SetProjectionGX() const; // at 0xC + virtual void CopyToG3D(nw4r::g3d::Camera) const; // at 0x10 + void ResetOrthographic(f32, f32, f32, f32, f32, f32); + void CopyFromAnother(const Frustum &); + void SetFovy(f32); + void ConvertToCanvasLU(f32, f32, f32 *, f32 *) const; + + static void SetGlobalScaleOffset(f32, f32, f32, f32); + static void GetGlobalScaleOffset(f32 *, f32 *, f32 *, f32 *); + + f32 GetScreenSizeToViewSize(f32, f32) const; void SetDirty(bool dirty) const { if (dirty) { @@ -56,27 +58,75 @@ public: } } - void SetFlag(Flag f) const { - mFlags |= f; + ProjectionType GetProjectionType() const { + return mProjType; + } + void SetProjectionType(ProjectionType type) { + mProjType = type; } CanvasMode GetCanvasMode() const { return mCanvasMode; } void SetCanvasMode(CanvasMode mode) { - if (mCanvasMode != mode) { + if (mode != mCanvasMode) { SetDirty(true); mCanvasMode = mode; } } + const nw4r::math::VEC2 &GetSize() const { + return mSize; + } + + u16 GetWidth() const { + return mSize.x; + } + f32 GetSizeX() const { + return mSize.x; + } + void SetSizeX(f32 sizeX) { + SetDirty(true); + mSize.x = sizeX; + } + + u16 GetHeight() const { + return mSize.y; + } + f32 GetSizeY() const { + return mSize.y; + } + void SetSizeY(f32 sizeY) { + SetDirty(true); + mSize.y = sizeY; + } + + void SetSize(const nw4r::math::VEC2 &size) { + // ??? + mSize.x = size.x; + SetDirty(true); + mSize.y = size.y; + } + + void SetNearZ(f32 nearZ) { + mNearZ = nearZ; + } + f32 GetNearZ() const { + return mNearZ; + } + + void SetFarZ(f32 farZ) { + mFarZ = farZ; + } + f32 GetFarZ() const { + return mFarZ; + } + void SetNearFar(f32 near, f32 far) { mNearZ = near; mFarZ = far; } - void ResetOrthographic(f32, f32, f32, f32, f32, f32); - void SetScale(const nw4r::math::VEC3 &scale) { mScale = scale; } @@ -84,11 +134,27 @@ public: mOffset = offset; } - const nw4r::math::VEC2 &GetSize() { - return mSize; + void SetFlag(u32 flag) { + mFlags |= flag; } -}; +private: + void SetProjectionPerspectiveGX_() const; + void SetProjectionOrthographicGX_() const; + + void CopyToG3D_Perspective_(nw4r::g3d::Camera) const; + void CopyToG3D_Orthographic_(nw4r::g3d::Camera) const; + + void CalcMtxPerspective_(nw4r::math::MTX44 *) const; + + void GetOrthographicParam_(f32 *) const; + void GetPerspectiveParam_(f32 *) const; + void GetOrthographicParam_(f32 *, f32 *, f32 *, f32 *) const; + +private: + static nw4r::math::VEC2 sGlobalScale; + static nw4r::math::VEC2 sGlobalOffset; +}; } // namespace EGG #endif diff --git a/include/egg/gfx/eggGXUtility.h b/include/egg/gfx/eggGXUtility.h index d3ac74b7..cba929e6 100644 --- a/include/egg/gfx/eggGXUtility.h +++ b/include/egg/gfx/eggGXUtility.h @@ -16,6 +16,7 @@ public: static void getTexObj(GXTexObj *, nw4r::g3d::ResTex, GXTexWrapMode, GXTexWrapMode, GXTexFilter, GXTexFilter); static void getNormalColor(GXColor &outColor, const Vector3f &vec); + static void setScaleOffsetPerspective(f32*, f32, f32, f32, f32); }; } // namespace EGG diff --git a/include/egg/gfx/eggGfxEngine.h b/include/egg/gfx/eggGfxEngine.h index 56e8d67b..20b6729b 100644 --- a/include/egg/gfx/eggGfxEngine.h +++ b/include/egg/gfx/eggGfxEngine.h @@ -2,12 +2,12 @@ #define EGG_GFXENGINE_H #include "common.h" -#include "rvl/GX.h" +#include "rvl/GX/GXTypes.h" namespace EGG { -namespace GfxEngine { - +class GfxEngine { +public: struct Configuration { /* 0x00 */ u16 efbWidth; /* 0x02 */ u16 efbHeight; @@ -23,7 +23,7 @@ struct Configuration { virtual ~Configuration() {} }; -} // namespace GfxEngine +}; } // namespace EGG diff --git a/include/egg/gfx/eggScreen.h b/include/egg/gfx/eggScreen.h index 699df321..df63bf81 100644 --- a/include/egg/gfx/eggScreen.h +++ b/include/egg/gfx/eggScreen.h @@ -1,41 +1,20 @@ #ifndef EGG_SCREEN_H #define EGG_SCREEN_H -#include "common.h" +#include "egg/egg_types.h" #include "egg/gfx/eggFrustum.h" namespace EGG { -// TODO: Fill out more class Screen : public Frustum { public: - Screen(); - Screen(const Screen &other); - Screen(f32, f32, f32, f32, Screen *, CanvasMode); + enum TVMode { TV_MODE_4_3, TV_MODE_16_9, TV_MODE_UNK_3, TV_MODE_MAX }; - virtual ~Screen() {} - virtual void SetProjectionGX() const override; - virtual void CopyToG3D(nw4r::g3d::Camera) const override; + typedef void (*ChangeTVModeFunc)(void *); - static void Initialize(const u16 *, const u16 *, Screen *); - static void SetTVModeDefault(); - - u8 TODO_0x3C[0x88 - 0x3C]; - - enum TVMode { - TV_MODE_1, - TV_MODE_2, - TV_MODE_3, - TV_MODE_4, - TV_MODE_MAX - }; - - struct TVModeInfo { - TVModeInfo() {} - u16 width; - u16 height; - f32 w_ratio; - f32 h_ratio; + struct UnkStruct { + UNKWORD field_0x00; + UNKWORD field_0x04; }; struct DataEfb { @@ -49,10 +28,26 @@ public: f32 z2; // at 0x14 } vp; - s32 sc_ox; // at 0x18 - s32 sc_oy; // at 0x1C + u32 sc_x; + u32 sc_y; + u32 sc_w; + u32 sc_h; + + s32 sc_ox; // at 0x28 + s32 sc_oy; // at 0x2C }; + struct TVModeInfo { + u16 width; + u16 height; + nw4r::math::VEC2 ratios; + }; + +public: + static void Initialize(const u16 *, const u16 *, Screen *); + static void SetTVMode(TVMode); + static void SetTVModeDefault(); + static u16 GetSizeXMax(TVMode mode) { return sTVModeInfo[mode].width; } @@ -74,11 +69,40 @@ public: return sTVMode; } + Screen(); + Screen(f32, f32, f32, f32, const Screen *, CanvasMode); + Screen(const Screen &); + + virtual ~Screen() {} // at 0x8 + virtual void SetProjectionGX() const; // at 0xC + virtual void CopyToG3D(nw4r::g3d::Camera) const; // at 0x10 + + const Screen *GetParent() const { + return mParent; + } + void SetParent(const Screen *parent); + void SetUnkFlag8(); + + void CopyFromAnother(const Screen &other); + void Reset(f32, f32, f32, f32, CanvasMode); + void GetPosSizeInEfb() const; + const DataEfb &GetDataEfb() const; + bool IsChangeEfb() const; + void CalcMatrixForDrawQuad(nw4r::math::MTX34 *, f32, f32, f32, f32) const; + void FillBufferGX(u32, GXColor, u32) const; + void GetGlobalPos(f32 *, f32 *) const; + +private: + const Screen *mParent; // at 0x3C + nw4r::math::VEC2 mPosition; // at 0x40 + nw4r::math::VEC2 field_0x44; + nw4r::math::VEC2 field_0x48; + mutable DataEfb mDataEfb; // at 0x58 + static TVMode sTVMode; static Screen *spRoot; - typedef void (*ChangeTVModeFunc)(void *); static ChangeTVModeFunc sChangeTVModeFunc; static void *spChangeTVModeFuncInfo; static TVModeInfo sTVModeInfo[Screen::TV_MODE_MAX]; diff --git a/include/egg/gfx/eggStateGX.h b/include/egg/gfx/eggStateGX.h index e575dcc8..bcc4e9f8 100644 --- a/include/egg/gfx/eggStateGX.h +++ b/include/egg/gfx/eggStateGX.h @@ -88,14 +88,16 @@ public: static bool GXSetDstAlpha(); // Unk func here static void GXSetProjection(Mtx44, int); - static void GXSetProjectionv(const f32 *); - static void GXSetViewport(f32, f32, f32, f32, f32, f32); - static void GZSetScissor(u32, u32, u32, u32); - static void GZSetScissorBoxOffset(s32, s32); + static void GXSetProjectionv_(const f32 *); + static void GXSetViewport_(f32, f32, f32, f32, f32, f32); + static void GXSetScissor_(u32, u32, u32, u32); + static void GXSetScissorBoxOffset_(s32, s32); static u16 s_commandFlag; static u16 s_flag; + static u16 s_widthEfb; + static u16 s_heightEfb; static GXColor sDefaultTexColor; }; diff --git a/src/d/lyt/d2d.cpp b/src/d/lyt/d2d.cpp index c69bada8..d33c741e 100644 --- a/src/d/lyt/d2d.cpp +++ b/src/d/lyt/d2d.cpp @@ -164,7 +164,7 @@ nw4r::lyt::AnimTransform *Layout_c::CreateAnimTransform(const void *animResBuf, Multi_c::Multi_c() : Base_c(0x80), mLayout(), mDrawInfo(), mpResAcc(nullptr), mFlags(0) { mDrawInfo.SetLocationAdjustScale(nw4r::math::VEC2( - (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1) / (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2), + (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_4_3) / (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_16_9), 1.0f )); mDrawInfo.SetLocationAdjust(true); @@ -207,8 +207,8 @@ void Multi_c::draw() { f32 far = 500.0f; EGG::Screen s; bool needsAdjust = NeedsScreenAdjustment(); - f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2); - f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1); + f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_UNK_3); + f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_16_9); f32 left = needsAdjust ? f1 * r.left / f2 : r.left; f32 right = needsAdjust ? f1 * r.right / f2 : r.right; diff --git a/src/egg/gfx/eggFrustum.cpp b/src/egg/gfx/eggFrustum.cpp index c060e519..d7c9e039 100644 --- a/src/egg/gfx/eggFrustum.cpp +++ b/src/egg/gfx/eggFrustum.cpp @@ -1,3 +1,240 @@ #include "egg/gfx/eggFrustum.h" -namespace EGG {} // namespace EGG +#include "egg/gfx/eggGXUtility.h" +#include "egg/gfx/eggStateGX.h" +#include "nw4r/math/math_arithmetic.h" + + +void eggFrustum_float_ordering() { + 1.0f; +} + +namespace EGG { +using namespace nw4r; + +Frustum::Frustum(ProjectionType proj, const math::VEC2 &size, f32 nearZ, f32 farZ, CanvasMode canvas) + : mProjType(proj), + mCanvasMode(canvas), + mSize(size), + mFovY(45.0f), + mTanFovY(2.4142134f), + mNearZ(nearZ), + mFarZ(farZ), + mOffset(0.0f, 0.0f), + mScale(1.0f, 1.0f, 1.0f), + mFlags(FLAG_DIRTY) {} + +Frustum::Frustum(const Frustum &other) { + CopyFromAnother(other); +} + +void Frustum::ResetOrthographic(f32 t, f32 b, f32 l, f32 r, f32 near, f32 far) { + 0.5f; + 2.0f; + + mProjType = PROJ_ORTHO; + mScale.z = 1.0f; + mScale.y = 1.0f; + mScale.x = 1.0f; + mSize.x = r - l; + if (mSize.x < 0.0f) { + mScale.x = -1.0f; + mSize.x *= -1.0f; + } + + mSize.y = t - b; + if (mSize.y >= 0.0f) { + SetCanvasMode(CANVASMODE_0); + mOffset = math::VEC2(0.5f * (r + l), 0.5f * (t + b)); + } else { + SetCanvasMode(CANVASMODE_1); + mOffset = math::VEC2(0.0f, t); + mSize.y *= -1.0f; + } + mNearZ = near; + mFarZ = far; + SetFlag(1); +} + +void Frustum::CopyFromAnother(const Frustum &other) { + mProjType = other.mProjType; + mCanvasMode = other.mCanvasMode; + mSize = other.mSize; + mFovY = other.mFovY; + mTanFovY = other.mTanFovY; + mNearZ = other.mNearZ; + mFarZ = other.mFarZ; + mOffset = other.mOffset; + mScale = other.mScale; + mFlags = other.mFlags; +} + +void Frustum::SetFovy(f32 fov) { + if (mFovY != fov) { + mFovY = fov; + f32 sin, cos; + + math::SinCosDeg(&sin, &cos, (f32)(f64)fov / 2.0f); + mTanFovY = cos / sin; + } +} + +void Frustum::ConvertToCanvasLU(f32 ix, f32 iy, f32 *ox, f32 *oy) const { + if (mCanvasMode == CANVASMODE_1) { + *ox = ix; + *oy = iy; + } else if (mCanvasMode == CANVASMODE_0) { + *ox = ix + (mSize.x * 0.5f); + *oy = -(iy - (mSize.y * 0.5f)); + } +} + +f32 Frustum::GetScreenSizeToViewSize(f32 p1, f32 p2) const { + if (mProjType != PROJ_PERSP) { + return p1; + } + return p1 * math::FAbs(p2) / (mSize.y * 0.5f * mTanFovY); +} + +void Frustum::SetProjectionGX() const { + if (mProjType == PROJ_ORTHO) { + SetProjectionOrthographicGX_(); + } else { + SetProjectionPerspectiveGX_(); + } +} + +void Frustum::CopyToG3D(g3d::Camera cam) const { + if (mProjType == PROJ_ORTHO) { + CopyToG3D_Orthographic_(cam); + } else { + CopyToG3D_Perspective_(cam); + } +} + +void Frustum::SetGlobalScaleOffset(f32 sx, f32 sy, f32 ox, f32 oy) { + sGlobalScale.x = sx; + sGlobalScale.y = sy; + sGlobalOffset.x = ox; + sGlobalOffset.y = oy; +} + +void Frustum::GetGlobalScaleOffset(f32 *sx, f32 *sy, f32 *ox, f32 *oy) { + *sx = sGlobalScale.x; + *sy = sGlobalScale.y; + *ox = sGlobalOffset.x; + *oy = sGlobalOffset.y; +} + +void Frustum::SetProjectionPerspectiveGX_() const { + f32 params[7]; + GetPerspectiveParam_(params); + StateGX::GXSetProjectionv_(params); +} + +void Frustum::SetProjectionOrthographicGX_() const { + f32 v[8]; + GetOrthographicParam_(v); + StateGX::GXSetProjectionv_(v); +} + +void Frustum::CopyToG3D_Perspective_(g3d::Camera cam) const { + math::MTX44 mtx; + f32 ratio = mSize.x / mSize.y; + cam.SetPerspective(mFovY, ratio, mNearZ, mFarZ); + CalcMtxPerspective_(&mtx); + cam.SetProjectionMtxDirectly(&mtx); +} + +void Frustum::CopyToG3D_Orthographic_(g3d::Camera cam) const { + f32 t, b, l, r; + GetOrthographicParam_(&t, &b, &l, &r); + cam.SetOrtho(t, b, l, r, mNearZ, mFarZ); +} + +void Frustum::CalcMtxPerspective_(math::MTX44 *out) const { + f32 params[7]; + GetPerspectiveParam_(params); + + out->m[0][3] = 0.0f; + out->m[0][1] = 0.0f; + out->m[0][0] = params[1]; + out->m[0][2] = params[2]; + + out->m[1][3] = 0.0f; + out->m[1][0] = 0.0f; + out->m[1][1] = params[3]; + out->m[1][2] = params[4]; + + out->m[2][1] = 0.0f; + out->m[2][0] = 0.0f; + out->m[2][2] = params[5]; + out->m[2][3] = params[6]; + + out->m[3][3] = 0.0f; + out->m[3][1] = 0.0f; + out->m[3][0] = 0.0f; + out->m[3][2] = -1.0f; +} + +void Frustum::GetPerspectiveParam_(f32 *p) const { + // NONMATCHING - FPR regswaps + f32 f1 = 1.0f / (mSize.x * 0.5f); + f32 f2 = 1.0f / (mSize.y * 0.5f); + p[0] = 0.0f; + p[1] = (mTanFovY / (mScale.x * (mSize.x / mSize.y))); + p[2] = mOffset.x * f1; + p[3] = mTanFovY / mScale.y; + p[4] = mOffset.y * f2; + + f32 z = -mNearZ / (mFarZ - mNearZ); + p[5] = z; + p[6] = mFarZ * z; + + GXUtility::setScaleOffsetPerspective(p, sGlobalScale.x, sGlobalScale.y, sGlobalOffset.x * f1, sGlobalOffset.y * f2); +} + +void Frustum::GetOrthographicParam_(f32 *p) const { + f32 t, b, l, r; + GetOrthographicParam_(&t, &b, &l, &r); + + f32 invHor = 1.0f / (r - l); + f32 invVert = 1.0f / (t - b); + f32 invZ = 1.0f / (mFarZ - mNearZ); + + p[0] = 1.0f; + p[1] = invHor * 2.0f; + p[3] = invVert * 2.0f; + + p[2] = invHor * -(r + l); + p[4] = invVert * -(t + b); + p[5] = -1.0f * invZ; + p[6] = -mFarZ * invZ; +} + +void Frustum::GetOrthographicParam_(f32 *pT, f32 *pB, f32 *pL, f32 *pR) const { + f32 adjOffsetX = mOffset.x + sGlobalOffset.x; + f32 adjOffsetY = mOffset.y + sGlobalOffset.y; + + if (mCanvasMode == CANVASMODE_0) { + const math::VEC2 adjScale(mScale.x * sGlobalScale.x, mScale.y * sGlobalScale.y); + + *pT = adjScale.y * ((0.5f * mSize.y) + adjOffsetY); + *pB = adjScale.y * ((-0.5f * mSize.y) + adjOffsetY); + *pL = adjScale.x * ((-0.5f * mSize.x) + adjOffsetX); + *pR = adjScale.x * ((0.5f * mSize.x) + adjOffsetX); + } else if (mCanvasMode == CANVASMODE_1) { + f32 adjScaleX = -(sGlobalScale.x - 1.0f) * mSize.x / 2.0f; + f32 adjScaleY = -(sGlobalScale.y - 1.0f) * mSize.y / 2.0f; + + *pT = adjScaleY + -sGlobalScale.y * adjOffsetY; + *pB = adjScaleY + -sGlobalScale.y * (adjOffsetY + mSize.y * -1.0f * mScale.y); + *pL = adjScaleX + sGlobalScale.x * adjOffsetX; + *pR = adjScaleX + sGlobalScale.x * (adjOffsetX + mSize.x * mScale.x); + } +} + +math::VEC2 Frustum::sGlobalScale(1.0f, 1.0f); +math::VEC2 Frustum::sGlobalOffset(0.0f, 0.0f); + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp index 9ecead4a..bf824907 100644 --- a/src/egg/gfx/eggPostEffectBase.cpp +++ b/src/egg/gfx/eggPostEffectBase.cpp @@ -153,7 +153,7 @@ void PostEffectBase::setProjection(const Screen &screen) { Screen screenCpy(screen); screenCpy.SetFlag(Screen::FLAG_0x40); - screenCpy.SetCanvasMode(Screen::CANVAS_1); + screenCpy.SetCanvasMode(Screen::CANVASMODE_1); screenCpy.SetProjectionType(Screen::PROJ_ORTHO); screenCpy.SetNearFar(0.0f, 1.0f); screenCpy.SetScale(sScale); diff --git a/src/egg/gfx/eggScreen.cpp b/src/egg/gfx/eggScreen.cpp index 66b80c4e..af26dc25 100644 --- a/src/egg/gfx/eggScreen.cpp +++ b/src/egg/gfx/eggScreen.cpp @@ -1,3 +1,343 @@ #include "egg/gfx/eggScreen.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/SC/scapi.h" + + +// ported from OGWS, though this class has evolved a fair bit + +using namespace nw4r; + +namespace EGG { + +Screen::TVMode Screen::sTVMode; +Screen::TVModeInfo Screen::sTVModeInfo[TV_MODE_MAX] = { + { + 608, 456, + nw4r::math::VEC2(1.0526316f, 1.0f), + }, + { + 812, 456, + nw4r::math::VEC2(0.7881773, 1.0f), + }, + { + 640, 456, + nw4r::math::VEC2(1.0f, 1.0f), + } +}; + +Screen *Screen::spRoot = nullptr; + +Screen::ChangeTVModeFunc Screen::sChangeTVModeFunc = nullptr; +void *Screen::spChangeTVModeFuncInfo = nullptr; + +math::VEC2 Screen::sCanvasScale(1.0f, 1.0f); +math::VEC2 Screen::sCanvasOffset(0.0f, 0.0f); + +void Screen::Initialize(const u16 *maxX, const u16 *maxY, Screen *userRoot) { + + sTVModeInfo[TV_MODE_4_3].width = maxX[0]; + sTVModeInfo[TV_MODE_4_3].height = maxY[0]; + + sTVModeInfo[TV_MODE_4_3].ratios.x = (f32)StateGX::s_widthEfb / (f32)sTVModeInfo[TV_MODE_4_3].width; + sTVModeInfo[TV_MODE_4_3].ratios.y = (f32)StateGX::s_heightEfb / (f32)sTVModeInfo[TV_MODE_4_3].height; + + sTVModeInfo[TV_MODE_16_9].width = maxX[1]; + sTVModeInfo[TV_MODE_16_9].height = maxY[1]; + + sTVModeInfo[TV_MODE_16_9].ratios.x = (f32)StateGX::s_widthEfb / (f32)sTVModeInfo[TV_MODE_16_9].width; + sTVModeInfo[TV_MODE_16_9].ratios.y = (f32)StateGX::s_heightEfb / (f32)sTVModeInfo[TV_MODE_16_9].height; + + sTVModeInfo[TV_MODE_UNK_3].width = StateGX::s_widthEfb; + sTVModeInfo[TV_MODE_UNK_3].height = StateGX::s_heightEfb; + + sTVModeInfo[TV_MODE_UNK_3].ratios.x = 1.0f; + sTVModeInfo[TV_MODE_UNK_3].ratios.y = 1.0f; + + static Screen defaultRoot; + defaultRoot.SetProjectionType(PROJ_ORTHO); + defaultRoot.SetCanvasMode(CANVASMODE_1); + defaultRoot.SetNearZ(0.0f); + defaultRoot.SetFarZ(1.0f); + defaultRoot.SetSize(math::VEC2(sTVModeInfo[sTVMode].width, sTVModeInfo[sTVMode].height)); + + userRoot = (userRoot == nullptr) ? &defaultRoot : userRoot; + spRoot = userRoot; + userRoot->mParent = nullptr; + SetTVMode(sTVMode); +} + +Screen::Screen() + : Frustum( + PROJ_PERSP, math::VEC2(sTVModeInfo[sTVMode].width, sTVModeInfo[sTVMode].height), 10.0f, 100000.0f, + CANVASMODE_1 + ) { + mParent = nullptr; + mPosition.x = 0.0f; + mPosition.y = 0.0f; + field_0x44.x = 0.0f; + field_0x44.y = 0.0f; + field_0x48.x = 0.0f; + field_0x48.y = 0.0f; + SetParent(nullptr); +} + +Screen::Screen(f32 x, f32 y, f32 w, f32 h, const Screen *userRoot, CanvasMode canvasMode) + : Frustum(PROJ_PERSP, math::VEC2(w, h), 10.0f, 100000.0f, canvasMode) { + mParent = nullptr; + mPosition.x = x; + mPosition.y = y; + field_0x44.x = 0.0f; + field_0x44.y = 0.0f; + field_0x48.x = 0.0f; + field_0x48.y = 0.0f; + SetParent(userRoot); +} + +Screen::Screen(const Screen &other) + : Frustum(other), + mPosition(other.mPosition), + mDataEfb(other.mDataEfb), + field_0x44(other.field_0x44), + field_0x48(other.field_0x48) { + SetParent(other.mParent); +} + +void Screen::SetProjectionGX() const { + if (!(mFlags & 0x40)) { + f32 sx, sy, ox, oy; + GetGlobalScaleOffset(&sx, &sy, &ox, &oy); + + SetGlobalScaleOffset(sCanvasScale.x, sCanvasScale.y, sCanvasOffset.x, sCanvasOffset.y); + Frustum::SetProjectionGX(); + + SetGlobalScaleOffset(sx, sy, ox, oy); + } else { + Frustum::SetProjectionGX(); + } + + const DataEfb &efb = GetDataEfb(); + + StateGX::GXSetViewport_(efb.vp.x1, efb.vp.y1, efb.vp.x2, efb.vp.y2, efb.vp.z1, efb.vp.z2); + StateGX::GXSetScissor_(efb.sc_x, efb.sc_y, efb.sc_w, efb.sc_h); + StateGX::GXSetScissorBoxOffset_(efb.sc_ox, efb.sc_oy); +} + +void Screen::CopyToG3D(g3d::Camera cam) const { + if (!(mFlags & 0x40)) { + f32 sx, sy, ox, oy; + GetGlobalScaleOffset(&sx, &sy, &ox, &oy); + + SetGlobalScaleOffset(sCanvasScale.x, sCanvasScale.y, sCanvasOffset.x, sCanvasOffset.y); + Frustum::CopyToG3D(cam); + + SetGlobalScaleOffset(sx, sy, ox, oy); + } else { + Frustum::CopyToG3D(cam); + } + + const DataEfb &efb = GetDataEfb(); + + f32 x1, x2, y1, y2; + f32 z1, z2; + + y2 = efb.vp.y2; + x2 = efb.vp.x2; + + y1 = efb.vp.y1; + x1 = efb.vp.x1; + + z2 = efb.vp.z2; + z1 = efb.vp.z1; + + cam.SetViewport(x1, y1, x2, y2); + cam.SetViewportZRange(z1, z2); + cam.SetScissor(efb.sc_x, efb.sc_y, efb.sc_w, efb.sc_h); + cam.SetScissorBoxOffset(efb.sc_ox, efb.sc_oy); +} + +void Screen::CopyFromAnother(const Screen &other) { + Frustum::CopyFromAnother(other); + + mPosition = other.mPosition; + field_0x44 = other.field_0x44; + field_0x48 = other.field_0x48; + mDataEfb = other.mDataEfb; + mParent = other.mParent; +} + +void Screen::Reset(f32 x, f32 y, f32 w, f32 h, CanvasMode mode) { + mPosition.x = x; + mPosition.y = y; + mSize.x = w; + SetDirty(true); + mSize.y = h; + SetCanvasMode(mode); +} + +void Screen::SetParent(const Screen *parent) { + const Screen *newParent = parent != nullptr ? parent : spRoot; + + if (mParent != newParent) { + SetDirty(true); + mParent = newParent; + } +} + +void Screen::SetUnkFlag8() { + if ((mFlags & 0x8) == 0) { + SetDirty(true); + } + mFlags |= 0x8; +} + +void Screen::GetPosSizeInEfb() const { + // TODO + const TVMode tvMode = (!(mFlags & 0x20)) ? sTVMode : TV_MODE_4_3; + const TVModeInfo &tvRatio = sTVModeInfo[tvMode]; + + f32 *px = &mDataEfb.vp.x1; + f32 *py = &mDataEfb.vp.y1; + GetGlobalPos(px, py); + + *px = sCanvasScale.x * *px; + *py = sCanvasScale.y * *py; + + *px *= tvRatio.ratios.x; + *py *= tvRatio.ratios.y; + + mDataEfb.sc_oy = 0; + mDataEfb.sc_ox = 0; + + const f32 x = *px; + if (x < 0.0f) { + *px = 0.0f; + + const s32 lx = static_cast(-x); + mDataEfb.sc_ox = lx - (lx & 0x1); + } + + const f32 y = *py; + if (y < 0.0f) { + *py = 0.0f; + + const s32 ly = static_cast(-y); + mDataEfb.sc_oy = ly - (ly & 0x1); + } + + if (mFlags & 0x2) { + *px -= static_cast(*px) & 0x1; + *py -= static_cast(*py) & 0x1; + } + + *px = static_cast(*px); + *py = static_cast(*py); + + mDataEfb.vp.x2 = mSize.x; + mDataEfb.vp.y2 = mSize.y; + + if (!(mFlags & 0x8)) { + mDataEfb.vp.x2 = mSize.x * tvRatio.ratios.x; + mDataEfb.vp.y2 = mSize.y * tvRatio.ratios.y; + } + + if (mFlags & 0x4) { + mDataEfb.vp.x2 -= static_cast(mDataEfb.vp.x2) & 0x3; + mDataEfb.vp.y2 -= static_cast(mDataEfb.vp.y2) & 0x3; + } + + mDataEfb.vp.x2 = (mDataEfb.vp.x2 >= 0.0f) ? mDataEfb.vp.x2 : 0.0f; + mDataEfb.vp.y2 = (mDataEfb.vp.y2 >= 0.0f) ? mDataEfb.vp.y2 : 0.0f; + + mDataEfb.vp.x2 = static_cast(mDataEfb.vp.x2); + mDataEfb.vp.y2 = static_cast(mDataEfb.vp.y2); +} + +const Screen::DataEfb &Screen::GetDataEfb() const { + if (IsChangeEfb()) { + GetPosSizeInEfb(); + mDataEfb.vp.z1 = 0.0f; + mDataEfb.vp.z2 = 1.0f; + SetDirty(false); + } + + return mDataEfb; +} + +bool Screen::IsChangeEfb() const { + if (mFlags & FLAG_DIRTY) { + return true; + } + + if (mParent != nullptr) { + return mParent->IsChangeEfb(); + } + + return false; +} + +void Screen::CalcMatrixForDrawQuad(math::MTX34 *mtx, f32 x, f32 y, f32 sx, f32 sy) const { + PSMTXScale(*mtx, sx, sy, 1.0f); + + mtx->m[0][3] = x; + mtx->m[1][3] = mCanvasMode == CANVASMODE_0 ? y - sy : y; + mtx->m[2][3] = 0.0f; +} + +void Screen::FillBufferGX(u32 flags, GXColor color, u32 r6) const { + if (flags != 0) { + math::MTX34 drawMtx; + Screen clone(mPosition.x, mPosition.y, mSize.x, mSize.y, mParent, CANVASMODE_1); + + if ((mFlags & 0x8) != 0) { + clone.SetUnkFlag8(); + } + + clone.SetNearZ(0.0f); + clone.SetFarZ(1.0f); + clone.SetFlag(0x40); + clone.SetProjectionType(PROJ_ORTHO); + + clone.SetProjectionGX(); + clone.CalcMatrixForDrawQuad(&drawMtx, 0.0f, 0.0f, mSize.x, mSize.y); + // Ugh + DrawGX::ClearEfb(drawMtx, (flags & 1) != 0, (flags & 2) != 0, (flags & 4) != 0, color, true); + } +} + +void Screen::GetGlobalPos(f32 *ox, f32 *oy) const { + f32 px, py; + const Screen *parent = GetParent(); + + if (parent != nullptr) { + parent->GetGlobalPos(&px, &py); + parent->ConvertToCanvasLU(mPosition.x, mPosition.y, ox, oy); + + *ox += px; + *oy += py; + } else { + + *ox = mPosition.x; + *oy = mPosition.y; + } +} + +void Screen::SetTVMode(TVMode tvMode) { + sTVMode = tvMode; + if (spRoot != nullptr) { + spRoot->SetSizeX(GetSizeXMax()); + spRoot->SetSizeY(GetSizeYMax()); + } + + if (sChangeTVModeFunc != nullptr) { + sChangeTVModeFunc(spChangeTVModeFuncInfo); + } +} + +void Screen::SetTVModeDefault() { + SetTVMode(SCGetAspectRatio() == SC_ASPECT_STD ? TV_MODE_4_3 : TV_MODE_16_9); +} + +} // namespace EGG diff --git a/src/m/m2d.cpp b/src/m/m2d.cpp index 9f591a69..3f2ec24d 100644 --- a/src/m/m2d.cpp +++ b/src/m/m2d.cpp @@ -295,9 +295,9 @@ void Simple_c::draw() { f32 near = 0.0f; f32 far = 500.0f; EGG::Screen s; - bool needsAdjust = EGG::Screen::GetTVMode() == EGG::Screen::TV_MODE_2; - f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2); - f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1); + bool needsAdjust = EGG::Screen::GetTVMode() == EGG::Screen::TV_MODE_16_9; + f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_16_9); + f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_4_3); f32 left = needsAdjust ? f1 * r.left / f2 : r.left; f32 right = needsAdjust ? f1 * r.right / f2 : r.right; From 5a84a6248a239b6c2e1571b2d9948e427b5b5aed Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 21 Mar 2025 00:48:22 +0100 Subject: [PATCH 21/62] Fix? --- config/SOUE01/symbols.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 1a95fda0..f30c4cc8 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26545,7 +26545,7 @@ __ct__Q23EGG7FrustumFQ33EGG7Frustum14ProjectionTypeRCQ34nw4r4math4VEC2ffQ33EGG7F __ct__Q23EGG7FrustumFRCQ23EGG7Frustum = .text:0x804A5FD0; // type:function size:0x3C ResetOrthographic__Q23EGG7FrustumFffffff = .text:0x804A6010; // type:function size:0x104 CopyFromAnother__Q23EGG7FrustumFRCQ23EGG7Frustum = .text:0x804A6120; // type:function size:0x74 -SetFovy__Q23EGG7FrustumFd = .text:0x804A61A0; // type:function size:0x68 +SetFovy__Q23EGG7FrustumFf = .text:0x804A61A0; // type:function size:0x68 ConvertToCanvasLU__Q23EGG7FrustumCFffPfPf = .text:0x804A6210; // type:function size:0x4C GetScreenSizeToViewSize__Q23EGG7FrustumCFff = .text:0x804A6260; // type:function size:0x30 SetProjectionGX__Q23EGG7FrustumCFv = .text:0x804A6290; // type:function size:0x14 From e2c2ec6c2dc0da586adcdfa2c71e54466d39dff0 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Thu, 20 Mar 2025 22:05:01 -0400 Subject: [PATCH 22/62] fix EGG::Matrix34f Copy assignment --- include/egg/math/eggMatrix.h | 5 +++++ src/REL/d/a/obj/d_a_obj_pool_cock.cpp | 7 +++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/egg/math/eggMatrix.h b/include/egg/math/eggMatrix.h index 89060283..a99a0698 100644 --- a/include/egg/math/eggMatrix.h +++ b/include/egg/math/eggMatrix.h @@ -24,6 +24,11 @@ struct Matrix34f { return arr[i]; } + Matrix34f &operator=(const Matrix34f &other) { + copyFrom(other); + return *this; + } + void rotateBaseX(Vector3f &, Matrix34f &); void rotateVectorChange(Vector3f &, Vector3f &, Matrix34f &); void inverseTo(Matrix34f &to) const; diff --git a/src/REL/d/a/obj/d_a_obj_pool_cock.cpp b/src/REL/d/a/obj/d_a_obj_pool_cock.cpp index f52cd41e..585c021c 100644 --- a/src/REL/d/a/obj/d_a_obj_pool_cock.cpp +++ b/src/REL/d/a/obj/d_a_obj_pool_cock.cpp @@ -52,10 +52,9 @@ int dAcOPoolCock_c::actorExecute() { position += velocity; position += mStts.mCcMove; updateMatrix(); - mMtx_c mdl1Transform; - mMtx_c mdl2Transform; - mdl1Transform = mWorldMtx; - mdl2Transform = mWorldMtx; + + mMtx_c mdl1Transform(mWorldMtx); + mMtx_c mdl2Transform(mWorldMtx); mMtx_c tmp1; mMtx_c tmp2; From 641c56b24a6549c0eaa626d332e80faf44be76f4 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 21 Mar 2025 10:56:05 +0100 Subject: [PATCH 23/62] wat --- config/SOUE01/symbols.txt | 14 ++-- include/egg/gfx/eggFrustum.h | 10 +-- include/egg/gfx/eggScreen.h | 31 +++++++-- src/egg/gfx/eggScreen.cpp | 125 ++++++++++++++++------------------- 4 files changed, 98 insertions(+), 82 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index f30c4cc8..784c1f1d 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26732,7 +26732,7 @@ CopyFromAnother__Q23EGG6ScreenFRCQ23EGG6Screen = .text:0x804B24C0; // type:funct Reset__Q23EGG6ScreenFffffQ33EGG7Frustum10CanvasMode = .text:0x804B2590; // type:function size:0x38 SetParent__Q23EGG6ScreenFPCQ23EGG6Screen = .text:0x804B25D0; // type:function size:0x30 SetUnkFlag8__Q23EGG6ScreenFv = .text:0x804B2600; // type:function size:0x24 -OnDirectEfb__Q23EGG6ScreenFv = .text:0x804B2630; // type:function size:0x4D8 +OnDirectEfb__Q23EGG6ScreenCFv = .text:0x804B2630; // type:function size:0x4D8 GetDataEfb__Q23EGG6ScreenCFv = .text:0x804B2B10; // type:function size:0x5C IsChangeEfb__Q23EGG6ScreenCFv = .text:0x804B2B70; // type:function size:0x2C CalcMatrixForDrawQuad__Q23EGG6ScreenCFPQ34nw4r4math5MTX34ffff = .text:0x804B2BA0; // type:function size:0xA8 @@ -26740,7 +26740,7 @@ FillBufferGX__Q23EGG6ScreenCFUl8_GXColorUl = .text:0x804B2C50; // type:function GetGlobalPos__Q23EGG6ScreenCFPfPf = .text:0x804B2D40; // type:function size:0xB0 SetTVMode__Q23EGG6ScreenFQ33EGG6Screen6TVMode = .text:0x804B2DF0; // type:function size:0xB0 SetTVModeDefault__Q23EGG6ScreenFv = .text:0x804B2EA0; // type:function size:0x34 -FUN_804b2ee0 = .text:0x804B2EE0; // type:function size:0x14C +fn_804B2EE0__Q23EGG6ScreenCFPfPfff = .text:0x804B2EE0; // type:function size:0x14C __sinit_\eggScreen_cpp = .text:0x804B3030; // type:function size:0x84 scope:local __ct__Q23EGG16ScreenEffectBaseFv = .text:0x804B30C0; // type:function size:0x18 __sinit_\eggScreenEffectBase_cpp = .text:0x804B30E0; // type:function size:0xC scope:local @@ -41174,11 +41174,11 @@ lbl_80576861 = .sbss:0x80576861; // type:object size:0x7 data:byte lbl_80576868 = .sbss:0x80576868; // type:object size:0x8 data:float sTVMode__Q23EGG6Screen = .sbss:0x80576870; // type:object size:0x4 data:4byte spRoot__Q23EGG6Screen = .sbss:0x80576874; // type:object size:0x4 data:4byte -lbl_80576878 = .sbss:0x80576878; // type:object size:0x4 data:4byte -lbl_8057687C = .sbss:0x8057687C; // type:object size:0x4 data:4byte -lbl_80576880 = .sbss:0x80576880; // type:object size:0x4 data:float -lbl_80576888 = .sbss:0x80576888; // type:object size:0x4 data:float -lbl_80576890 = .sbss:0x80576890; // type:object size:0x8 data:byte +sChangeTVModeFunc__Q23EGG6Screen = .sbss:0x80576878; // type:object size:0x4 data:4byte +spChangeTVModeFuncInfo__Q23EGG6Screen = .sbss:0x8057687C; // type:object size:0x4 data:4byte +sCanvasScale__Q23EGG6Screen = .sbss:0x80576880; // type:object size:0x8 data:float +sCanvasOffset__Q23EGG6Screen = .sbss:0x80576888; // type:object size:0x8 data:float +@GUARD@Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen@defaultRoot = .sbss:0x80576890; // type:object size:0x1 data:byte lbl_80576898 = .sbss:0x80576898; // type:object size:0x8 data:4byte s_widthEfb__Q23EGG7StateGX = .sbss:0x805768A0; // type:object size:0x2 data:2byte s_heightEfb__Q23EGG7StateGX = .sbss:0x805768A2; // type:object size:0x2 data:2byte diff --git a/include/egg/gfx/eggFrustum.h b/include/egg/gfx/eggFrustum.h index 5adbc40e..877a4940 100644 --- a/include/egg/gfx/eggFrustum.h +++ b/include/egg/gfx/eggFrustum.h @@ -8,6 +8,10 @@ class Frustum { public: enum Flag { FLAG_DIRTY = (1 << 0), + FLAG_0x02 = (1 << 1), + FLAG_0x04 = (1 << 2), + FLAG_0x08 = (1 << 3), + FLAG_0x20 = (1 << 5), FLAG_0x40 = (1 << 6), }; @@ -102,10 +106,8 @@ public: } void SetSize(const nw4r::math::VEC2 &size) { - // ??? - mSize.x = size.x; - SetDirty(true); - mSize.y = size.y; + SetSizeX(size.x); + SetSizeY(size.y); } void SetNearZ(f32 nearZ) { diff --git a/include/egg/gfx/eggScreen.h b/include/egg/gfx/eggScreen.h index df63bf81..f2638357 100644 --- a/include/egg/gfx/eggScreen.h +++ b/include/egg/gfx/eggScreen.h @@ -3,12 +3,18 @@ #include "egg/egg_types.h" #include "egg/gfx/eggFrustum.h" +#include "egg/gfx/eggStateGX.h" namespace EGG { class Screen : public Frustum { public: - enum TVMode { TV_MODE_4_3, TV_MODE_16_9, TV_MODE_UNK_3, TV_MODE_MAX }; + enum TVMode { + TV_MODE_4_3, + TV_MODE_16_9, + TV_MODE_UNK_3, + TV_MODE_MAX + }; typedef void (*ChangeTVModeFunc)(void *); @@ -69,6 +75,14 @@ public: return sTVMode; } + TVMode GetComputedTVMode() const { + if ((mFlags & FLAG_0x20) == 0) { + return (mFlags & FLAG_0x08) == 0 ? sTVMode : TV_MODE_UNK_3; + } else { + return TV_MODE_4_3; + } + } + Screen(); Screen(f32, f32, f32, f32, const Screen *, CanvasMode); Screen(const Screen &); @@ -85,18 +99,27 @@ public: void CopyFromAnother(const Screen &other); void Reset(f32, f32, f32, f32, CanvasMode); - void GetPosSizeInEfb() const; + void OnDirectEfb() const; const DataEfb &GetDataEfb() const; bool IsChangeEfb() const; void CalcMatrixForDrawQuad(nw4r::math::MTX34 *, f32, f32, f32, f32) const; void FillBufferGX(u32, GXColor, u32) const; void GetGlobalPos(f32 *, f32 *) const; + void fn_804B2EE0(f32 *, f32 *, f32, f32) const; + + f32 ScaleByX(f32 val) const { + return val * StateGX::s_widthEfb / GetSizeXMax(GetComputedTVMode()); + } + + f32 ScaleByY(f32 val) const { + return val * StateGX::s_heightEfb / GetSizeYMax(GetComputedTVMode()); + } private: const Screen *mParent; // at 0x3C nw4r::math::VEC2 mPosition; // at 0x40 - nw4r::math::VEC2 field_0x44; - nw4r::math::VEC2 field_0x48; + nw4r::math::VEC2 field_0x48; // at 0x48 + nw4r::math::VEC2 field_0x50; // at 0x50 mutable DataEfb mDataEfb; // at 0x58 static TVMode sTVMode; diff --git a/src/egg/gfx/eggScreen.cpp b/src/egg/gfx/eggScreen.cpp index af26dc25..18c41717 100644 --- a/src/egg/gfx/eggScreen.cpp +++ b/src/egg/gfx/eggScreen.cpp @@ -5,7 +5,6 @@ #include "egg/gfx/eggStateGX.h" #include "rvl/SC/scapi.h" - // ported from OGWS, though this class has evolved a fair bit using namespace nw4r; @@ -37,22 +36,21 @@ math::VEC2 Screen::sCanvasScale(1.0f, 1.0f); math::VEC2 Screen::sCanvasOffset(0.0f, 0.0f); void Screen::Initialize(const u16 *maxX, const u16 *maxY, Screen *userRoot) { - sTVModeInfo[TV_MODE_4_3].width = maxX[0]; sTVModeInfo[TV_MODE_4_3].height = maxY[0]; - + sTVModeInfo[TV_MODE_4_3].ratios.x = (f32)StateGX::s_widthEfb / (f32)sTVModeInfo[TV_MODE_4_3].width; sTVModeInfo[TV_MODE_4_3].ratios.y = (f32)StateGX::s_heightEfb / (f32)sTVModeInfo[TV_MODE_4_3].height; - + sTVModeInfo[TV_MODE_16_9].width = maxX[1]; sTVModeInfo[TV_MODE_16_9].height = maxY[1]; sTVModeInfo[TV_MODE_16_9].ratios.x = (f32)StateGX::s_widthEfb / (f32)sTVModeInfo[TV_MODE_16_9].width; sTVModeInfo[TV_MODE_16_9].ratios.y = (f32)StateGX::s_heightEfb / (f32)sTVModeInfo[TV_MODE_16_9].height; - + sTVModeInfo[TV_MODE_UNK_3].width = StateGX::s_widthEfb; sTVModeInfo[TV_MODE_UNK_3].height = StateGX::s_heightEfb; - + sTVModeInfo[TV_MODE_UNK_3].ratios.x = 1.0f; sTVModeInfo[TV_MODE_UNK_3].ratios.y = 1.0f; @@ -77,10 +75,10 @@ Screen::Screen() mParent = nullptr; mPosition.x = 0.0f; mPosition.y = 0.0f; - field_0x44.x = 0.0f; - field_0x44.y = 0.0f; field_0x48.x = 0.0f; field_0x48.y = 0.0f; + field_0x50.x = 0.0f; + field_0x50.y = 0.0f; SetParent(nullptr); } @@ -89,10 +87,10 @@ Screen::Screen(f32 x, f32 y, f32 w, f32 h, const Screen *userRoot, CanvasMode ca mParent = nullptr; mPosition.x = x; mPosition.y = y; - field_0x44.x = 0.0f; - field_0x44.y = 0.0f; field_0x48.x = 0.0f; field_0x48.y = 0.0f; + field_0x50.x = 0.0f; + field_0x50.y = 0.0f; SetParent(userRoot); } @@ -100,8 +98,8 @@ Screen::Screen(const Screen &other) : Frustum(other), mPosition(other.mPosition), mDataEfb(other.mDataEfb), - field_0x44(other.field_0x44), - field_0x48(other.field_0x48) { + field_0x48(other.field_0x48), + field_0x50(other.field_0x50) { SetParent(other.mParent); } @@ -162,8 +160,8 @@ void Screen::CopyFromAnother(const Screen &other) { Frustum::CopyFromAnother(other); mPosition = other.mPosition; - field_0x44 = other.field_0x44; field_0x48 = other.field_0x48; + field_0x50 = other.field_0x50; mDataEfb = other.mDataEfb; mParent = other.mParent; } @@ -187,77 +185,64 @@ void Screen::SetParent(const Screen *parent) { } void Screen::SetUnkFlag8() { - if ((mFlags & 0x8) == 0) { + if ((mFlags & FLAG_0x08) == 0) { SetDirty(true); } - mFlags |= 0x8; + mFlags |= FLAG_0x08; } -void Screen::GetPosSizeInEfb() const { - // TODO - const TVMode tvMode = (!(mFlags & 0x20)) ? sTVMode : TV_MODE_4_3; - const TVModeInfo &tvRatio = sTVModeInfo[tvMode]; +void Screen::OnDirectEfb() const { + f32 &x1 = mDataEfb.vp.x1; + f32 &y1 = mDataEfb.vp.y1; + if (mParent == nullptr) { + x1 = mPosition.x * sCanvasScale.x; + y1 = mPosition.y * sCanvasScale.y; + } else { + mParent->fn_804B2EE0(&x1, &y1, mPosition.x, mPosition.y); + } - f32 *px = &mDataEfb.vp.x1; - f32 *py = &mDataEfb.vp.y1; - GetGlobalPos(px, py); + // TODO: Make this work without temporaries? - *px = sCanvasScale.x * *px; - *py = sCanvasScale.y * *py; - - *px *= tvRatio.ratios.x; - *py *= tvRatio.ratios.y; + mDataEfb.sc_x = x1 + ScaleByX(field_0x48.x); + mDataEfb.sc_y = y1 + ScaleByY(field_0x48.y); mDataEfb.sc_oy = 0; mDataEfb.sc_ox = 0; - - const f32 x = *px; - if (x < 0.0f) { - *px = 0.0f; - - const s32 lx = static_cast(-x); - mDataEfb.sc_ox = lx - (lx & 0x1); + if (x1 < 0.0f) { + int x1_i = x1; + int x1_in = -x1_i; + mDataEfb.sc_ox = (x1_in - (x1_in & 1)); + x1 = x1 - x1_i; + } + if (y1 < 0.0f) { + int y1_i = y1; + int y1_in = -y1_i; + mDataEfb.sc_oy = (y1_in - (y1_in & 1)); + y1 = y1 - y1_i; } - const f32 y = *py; - if (y < 0.0f) { - *py = 0.0f; - - const s32 ly = static_cast(-y); - mDataEfb.sc_oy = ly - (ly & 0x1); + if ((mFlags & FLAG_0x02) != 0) { + x1 = x1 - (((int)x1) & 1); + y1 = y1 - (((int)y1) & 1); } - if (mFlags & 0x2) { - *px -= static_cast(*px) & 0x1; - *py -= static_cast(*py) & 0x1; + mDataEfb.vp.x2 = ScaleByX(mSize.x); + mDataEfb.vp.y2 = ScaleByY(mSize.y); + + if ((mFlags & FLAG_0x04) != 0) { + mDataEfb.vp.x2 -= ((int)mDataEfb.vp.x2 & 3); + mDataEfb.vp.y2 -= ((int)mDataEfb.vp.y2 & 3); } + mDataEfb.vp.x2 = (int)mDataEfb.vp.x2; + mDataEfb.vp.y2 = (int)mDataEfb.vp.y2; - *px = static_cast(*px); - *py = static_cast(*py); - - mDataEfb.vp.x2 = mSize.x; - mDataEfb.vp.y2 = mSize.y; - - if (!(mFlags & 0x8)) { - mDataEfb.vp.x2 = mSize.x * tvRatio.ratios.x; - mDataEfb.vp.y2 = mSize.y * tvRatio.ratios.y; - } - - if (mFlags & 0x4) { - mDataEfb.vp.x2 -= static_cast(mDataEfb.vp.x2) & 0x3; - mDataEfb.vp.y2 -= static_cast(mDataEfb.vp.y2) & 0x3; - } - - mDataEfb.vp.x2 = (mDataEfb.vp.x2 >= 0.0f) ? mDataEfb.vp.x2 : 0.0f; - mDataEfb.vp.y2 = (mDataEfb.vp.y2 >= 0.0f) ? mDataEfb.vp.y2 : 0.0f; - - mDataEfb.vp.x2 = static_cast(mDataEfb.vp.x2); - mDataEfb.vp.y2 = static_cast(mDataEfb.vp.y2); + mDataEfb.sc_w = mDataEfb.vp.x2 - ScaleByX(field_0x48.x + field_0x50.x); + mDataEfb.sc_h = mDataEfb.vp.y2 - ScaleByY(field_0x48.y + field_0x50.y); } const Screen::DataEfb &Screen::GetDataEfb() const { if (IsChangeEfb()) { - GetPosSizeInEfb(); + OnDirectEfb(); mDataEfb.vp.z1 = 0.0f; mDataEfb.vp.z2 = 1.0f; SetDirty(false); @@ -303,7 +288,7 @@ void Screen::FillBufferGX(u32 flags, GXColor color, u32 r6) const { clone.SetProjectionGX(); clone.CalcMatrixForDrawQuad(&drawMtx, 0.0f, 0.0f, mSize.x, mSize.y); // Ugh - DrawGX::ClearEfb(drawMtx, (flags & 1) != 0, (flags & 2) != 0, (flags & 4) != 0, color, true); + DrawGX::ClearEfb(drawMtx, (flags & 1), (flags & 2), (flags & 4), color, true); } } @@ -318,7 +303,6 @@ void Screen::GetGlobalPos(f32 *ox, f32 *oy) const { *ox += px; *oy += py; } else { - *ox = mPosition.x; *oy = mPosition.y; } @@ -340,4 +324,11 @@ void Screen::SetTVModeDefault() { SetTVMode(SCGetAspectRatio() == SC_ASPECT_STD ? TV_MODE_4_3 : TV_MODE_16_9); } +void Screen::fn_804B2EE0(f32 *ox, f32 *oy, f32 a, f32 b) const { + GetGlobalPos(ox, oy); + ConvertToCanvasLU(a, b, &a, &b); + *ox = ScaleByX((*ox + a)); + *oy = ScaleByY((*oy + b)); +} + } // namespace EGG From 4c9213be54d75373deacbe65258db19c978e920a Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 21 Mar 2025 11:29:27 +0100 Subject: [PATCH 24/62] eggScreen OK (thanks kiwi!) --- configure.py | 2 +- src/egg/gfx/eggScreen.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/configure.py b/configure.py index 53e783db..0cebcd33 100644 --- a/configure.py +++ b/configure.py @@ -896,7 +896,7 @@ config.libs = [ Object(Matching, "egg/gfx/eggPostEffectMask.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectMaskDOF.cpp"), Object(Matching, "egg/gfx/eggPostEffectSimple.cpp"), - Object(NonMatching, "egg/gfx/eggScreen.cpp"), + Object(Matching, "egg/gfx/eggScreen.cpp"), Object(Matching, "egg/gfx/eggScreenEffectBase.cpp"), Object(NonMatching, "egg/gfx/eggScreenEffectBlur.cpp"), # Unknown Guess Object(NonMatching, "egg/gfx/eggStateEfb.cpp"), diff --git a/src/egg/gfx/eggScreen.cpp b/src/egg/gfx/eggScreen.cpp index 18c41717..768c4b2c 100644 --- a/src/egg/gfx/eggScreen.cpp +++ b/src/egg/gfx/eggScreen.cpp @@ -287,8 +287,9 @@ void Screen::FillBufferGX(u32 flags, GXColor color, u32 r6) const { clone.SetProjectionGX(); clone.CalcMatrixForDrawQuad(&drawMtx, 0.0f, 0.0f, mSize.x, mSize.y); - // Ugh - DrawGX::ClearEfb(drawMtx, (flags & 1), (flags & 2), (flags & 4), color, true); + DrawGX::ClearEfb( + drawMtx, (flags & 1) ? true : false, (flags & 2) ? true : false, (flags & 4) ? true : false, color, true + ); } } From b6505d23ad73d1f0a32ef23dd57f85092a0e2745 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 21 Mar 2025 20:38:00 +0100 Subject: [PATCH 25/62] StateGX OK --- config/SOUE01/splits.txt | 4 + config/SOUE01/symbols.txt | 46 ++--- configure.py | 2 +- include/egg/core/eggDisplay.h | 9 + include/egg/gfx/eggStateGX.h | 113 ++++++----- include/rvl/GX/GXPixel.h | 4 + include/rvl/GX/GXTexture.h | 3 + include/rvl/GX/GXTransform.h | 2 +- src/egg/gfx/eggCapTexture.cpp | 2 +- src/egg/gfx/eggStateGX.cpp | 322 ++++++++++++++++++++++++++++++- src/egg/gfx/eggTextureBuffer.cpp | 2 +- 11 files changed, 429 insertions(+), 80 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index c6b4d2ec..b49f39fb 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2335,6 +2335,10 @@ egg/gfx/eggStateEfb.cpp: egg/gfx/eggStateGX.cpp: .text start:0x804B4610 end:0x804B53EC + .rodata start:0x804FBDA0 end:0x804FBE08 + .sbss start:0x805768A0 end:0x805768B8 + .sdata2 start:0x8057F890 end:0x8057F8B0 + .bss start:0x806750A0 end:0x80675190 egg/gfx/eggTextureBuffer.cpp: .text start:0x804B53F0 end:0x804B59DC diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 784c1f1d..4668d25d 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -22396,15 +22396,15 @@ GXInitFogAdjTable = .text:0x803C0CA0; // type:function size:0x160 GXSetFogRangeAdj = .text:0x803C0E00; // type:function size:0x110 GXSetBlendMode = .text:0x803C0F10; // type:function size:0x50 GXSetColorUpdate = .text:0x803C0F60; // type:function size:0x2C -FUN_803c0f90 = .text:0x803C0F90; // type:function size:0x14 +GXGetColorUpdate = .text:0x803C0F90; // type:function size:0x14 GXSetAlphaUpdate = .text:0x803C0FB0; // type:function size:0x2C -FUN_803c0fe0 = .text:0x803C0FE0; // type:function size:0x14 +GXGetAlphaUpdate = .text:0x803C0FE0; // type:function size:0x14 GXSetZMode = .text:0x803C1000; // type:function size:0x34 GXSetZCompLoc = .text:0x803C1040; // type:function size:0x30 GXSetPixelFmt = .text:0x803C1070; // type:function size:0xA8 -FUN_803c1120 = .text:0x803C1120; // type:function size:0x20 +GXGetPixelFmt = .text:0x803C1120; // type:function size:0x20 GXSetDither = .text:0x803C1140; // type:function size:0x2C -FUN_803c1170 = .text:0x803C1170; // type:function size:0x14 +GXGetDither = .text:0x803C1170; // type:function size:0x14 GXSetDstAlpha = .text:0x803C1190; // type:function size:0x30 GXSetFieldMask = .text:0x803C11C0; // type:function size:0x34 GXSetFieldMode = .text:0x803C1200; // type:function size:0x70 @@ -26764,10 +26764,10 @@ FUN_804b4310 = .text:0x804B4310; // type:function size:0x23C FUN_804b4550 = .text:0x804B4550; // type:function size:0xA0 FUN_804b45f0 = .text:0x804B45F0; // type:function size:0xC FUN_804b4600 = .text:0x804B4600; // type:function size:0xC -FUN_804b4610 = .text:0x804B4610; // type:function size:0x28 +texRegionCallback__24@unnamed@eggStateGX_cpp@FPC9_GXTexObj11_GXTexMapID = .text:0x804B4610; // type:function size:0x28 initialize__Q23EGG7StateGXFUsUs8_GXColor11_GXPixelFmt = .text:0x804B4640; // type:function size:0x114 frameInit__Q23EGG7StateGXFv = .text:0x804B4760; // type:function size:0xA8 -FUN_804b4810 = .text:0x804B4810; // type:function size:0x160 +setTMemLayout__Q23EGG7StateGXFi = .text:0x804B4810; // type:function size:0x160 resetGX__Q23EGG7StateGXFv = .text:0x804B4970; // type:function size:0x48 resetVtx__Q23EGG7StateGXFv = .text:0x804B49C0; // type:function size:0x13C resetColorChannel__Q23EGG7StateGXFv = .text:0x804B4B00; // type:function size:0xB8 @@ -26777,15 +26777,15 @@ resetTexGen__Q23EGG7StateGXFv = .text:0x804B4CB0; // type:function size:0xB8 resetTev__Q23EGG7StateGXFv = .text:0x804B4D70; // type:function size:0x17C resetPE__Q23EGG7StateGXFv = .text:0x804B4EF0; // type:function size:0xB0 resetGXCache__Q23EGG7StateGXFv = .text:0x804B4FA0; // type:function size:0x40 -EGG__StateGX__GXSetPixelFmt_ = .text:0x804B4FE0; // type:function size:0xAC +GXSetPixelFmt___Q23EGG7StateGXF11_GXPixelFmt9_GXZFmt16 = .text:0x804B4FE0; // type:function size:0xAC invalidateTexAllGX__Q23EGG7StateGXFv = .text:0x804B5090; // type:function size:0x4 GXSetColorUpdate___Q23EGG7StateGXFb = .text:0x804B50A0; // type:function size:0x4C GXSetAlphaUpdate___Q23EGG7StateGXFb = .text:0x804B50F0; // type:function size:0x4C GXSetDither___Q23EGG7StateGXFb = .text:0x804B5140; // type:function size:0x4C -GXCopyTex__Q23EGG7StateGXFPvb = .text:0x804B5190; // type:function size:0x8 +GXCopyTex___Q23EGG7StateGXFPvb = .text:0x804B5190; // type:function size:0x8 GXSetDstAlpha___Q23EGG7StateGXFbUc = .text:0x804B51A0; // type:function size:0x4C -FUN_804b51f0 = .text:0x804B51F0; // type:function size:0x108 -FUN_804b5300 = .text:0x804B5300; // type:function size:0x2C +CalculateScreenScissor__Q23EGG7StateGXFPCfPUl = .text:0x804B51F0; // type:function size:0x108 +GXSetProjection___Q23EGG7StateGXFPA4_f17_GXProjectionType = .text:0x804B5300; // type:function size:0x2C GXSetProjectionv___Q23EGG7StateGXFPCf = .text:0x804B5330; // type:function size:0x2C GXSetViewport___Q23EGG7StateGXFffffff = .text:0x804B5360; // type:function size:0x2C GXSetScissor___Q23EGG7StateGXFUlUlUlUl = .text:0x804B5390; // type:function size:0x2C @@ -29176,10 +29176,10 @@ lbl_804FBD50 = .rodata:0x804FBD50; // type:object size:0x10 data:float lbl_804FBD60 = .rodata:0x804FBD60; // type:object size:0x10 data:float lbl_804FBD70 = .rodata:0x804FBD70; // type:object size:0x18 lbl_804FBD88 = .rodata:0x804FBD88; // type:object size:0x18 data:4byte -lbl_804FBDA0 = .rodata:0x804FBDA0; // type:object size:0x30 -lbl_804FBDD0 = .rodata:0x804FBDD0; // type:object size:0x10 -lbl_804FBDE0 = .rodata:0x804FBDE0; // type:object size:0x10 -lbl_804FBDF0 = .rodata:0x804FBDF0; // type:object size:0x18 +identity__24@unnamed@eggStateGX_cpp@ = .rodata:0x804FBDA0; // type:object size:0x30 +@LOCAL@setTMemLayout__Q23EGG7StateGXFi@numbers = .rodata:0x804FBDD0; // type:object size:0x10 +@LOCAL@setTMemLayout__Q23EGG7StateGXFi@offsets@0 = .rodata:0x804FBDE0; // type:object size:0x10 +@LOCAL@resetIndirect__Q23EGG7StateGXFv@ind = .rodata:0x804FBDF0; // type:object size:0x18 lbl_804FBE08 = .rodata:0x804FBE08; // type:object size:0x10 data:4byte lbl_804FBE18 = .rodata:0x804FBE18; // type:object size:0x40 lbl_804FBE58 = .rodata:0x804FBE58; // type:object size:0xC @@ -41182,11 +41182,11 @@ sCanvasOffset__Q23EGG6Screen = .sbss:0x80576888; // type:object size:0x8 data:fl lbl_80576898 = .sbss:0x80576898; // type:object size:0x8 data:4byte s_widthEfb__Q23EGG7StateGX = .sbss:0x805768A0; // type:object size:0x2 data:2byte s_heightEfb__Q23EGG7StateGX = .sbss:0x805768A2; // type:object size:0x2 data:2byte -lbl_805768A4 = .sbss:0x805768A4; // type:object size:0x4 data:4byte -lbl_805768A8 = .sbss:0x805768A8; // type:object size:0x4 data:4byte -sDefaultTexColor__Q23EGG7StateGX = .sbss:0x805768AC; // type:object size:0x1 data:byte +s_pixFormat__Q23EGG7StateGX = .sbss:0x805768A4; // type:object size:0x4 data:4byte +s_zFmt16__Q23EGG7StateGX = .sbss:0x805768A8; // type:object size:0x4 data:4byte +s_clearEfb__Q23EGG7StateGX = .sbss:0x805768AC; // type:object size:0x4 data:byte s_flag__Q23EGG7StateGX = .sbss:0x805768B0; // type:object size:0x2 data:2byte -s_commandFlag__Q23EGG7StateGX = .sbss:0x805768B2; // type:object size:0x6 data:2byte +s_commandFlag__Q23EGG7StateGX = .sbss:0x805768B2; // type:object size:0x2 data:2byte spHead__Q23EGG13TextureBuffer = .sbss:0x805768B8; // type:object size:0x4 data:4byte spTailNotJoin__Q23EGG13TextureBuffer = .sbss:0x805768BC; // type:object size:0x4 data:4byte spBufferAll__Q23EGG13TextureBuffer = .sbss:0x805768C0; // type:object size:0x4 data:4byte @@ -48203,7 +48203,7 @@ lbl_8057F874 = .sdata2:0x8057F874; // type:object size:0x4 data:float lbl_8057F878 = .sdata2:0x8057F878; // type:object size:0x4 data:float lbl_8057F880 = .sdata2:0x8057F880; // type:object size:0x8 data:double lbl_8057F888 = .sdata2:0x8057F888; // type:object size:0x4 data:float -lbl_8057F890 = .sdata2:0x8057F890; // type:object size:0x4 data:4byte +white__24@unnamed@eggStateGX_cpp@ = .sdata2:0x8057F890; // type:object size:0x4 data:4byte lbl_8057F894 = .sdata2:0x8057F894; // type:object size:0x4 data:float lbl_8057F898 = .sdata2:0x8057F898; // type:object size:0x4 data:float lbl_8057F89C = .sdata2:0x8057F89C; // type:object size:0x4 data:float @@ -49810,10 +49810,10 @@ lbl_80675010 = .bss:0x80675010; // type:object size:0x30 lbl_80675040 = .bss:0x80675040; // type:object size:0x18 data:float lbl_80675058 = .bss:0x80675058; // type:object size:0x18 data:float lbl_80675070 = .bss:0x80675070; // type:object size:0x30 data:float -lbl_806750A0 = .bss:0x806750A0; // type:object size:0x20 -lbl_806750C0 = .bss:0x806750C0; // type:object size:0xA8 data:4byte -lbl_80675168 = .bss:0x80675168; // type:object size:0x18 -lbl_80675180 = .bss:0x80675180; // type:object size:0x10 +sDefaultTexObj__Q23EGG7StateGX = .bss:0x806750A0; // type:object size:0x20 +s_tmem_layout__Q23EGG7StateGX = .bss:0x806750C0; // type:object size:0xA8 data:4byte +s_cacheGX__Q23EGG7StateGX = .bss:0x80675168; // type:object size:0x18 +@LOCAL@initialize__Q23EGG7StateGXFUsUs8_GXColor11_GXPixelFmt@sDefaultTexObjData = .bss:0x80675180; // type:object size:0x10 spBufferTable__Q23EGG13TextureBuffer = .bss:0x80675190; // type:object size:0x200 data:4byte sTasks__Q23EGG18AudioRmtSpeakerMgr = .bss:0x80675390; // type:object size:0xF0 sMoveParamMgr__Q23EGG12AudioUtility = .bss:0x80675480; // type:object size:0xC diff --git a/configure.py b/configure.py index 0cebcd33..a03f64c2 100644 --- a/configure.py +++ b/configure.py @@ -900,7 +900,7 @@ config.libs = [ Object(Matching, "egg/gfx/eggScreenEffectBase.cpp"), Object(NonMatching, "egg/gfx/eggScreenEffectBlur.cpp"), # Unknown Guess Object(NonMatching, "egg/gfx/eggStateEfb.cpp"), - Object(NonMatching, "egg/gfx/eggStateGX.cpp"), + Object(Matching, "egg/gfx/eggStateGX.cpp"), Object(Matching, "egg/gfx/eggTextureBuffer.cpp"), ], ), diff --git a/include/egg/core/eggDisplay.h b/include/egg/core/eggDisplay.h index 08c02c1e..cdf2fe7a 100644 --- a/include/egg/core/eggDisplay.h +++ b/include/egg/core/eggDisplay.h @@ -5,6 +5,7 @@ #include "egg/core/eggSystem.h" // for BaseSystem config #include "egg/core/eggVideo.h" #include "egg/prim/eggBitFlag.h" +#include "nw4r/ut/ut_Color.h" #include "nw4r/ut.h" // IWYU pragma: export #include "rvl/VI.h" // IWYU pragma: export @@ -49,6 +50,14 @@ public: void calcFrequency(); void setBlack(bool b) {} + nw4r::ut::Color getClearColor() const { + return mClearColor; + } + + void setClearColor(nw4r::ut::Color color) { + mClearColor = color; + } + public: static u32 sTickPeriod; }; diff --git a/include/egg/gfx/eggStateGX.h b/include/egg/gfx/eggStateGX.h index bcc4e9f8..9dcdf342 100644 --- a/include/egg/gfx/eggStateGX.h +++ b/include/egg/gfx/eggStateGX.h @@ -2,64 +2,71 @@ #define EGG_STATE_GX_H #include "common.h" +#include "rvl/GX/GXTexture.h" #include "rvl/GX/GXTypes.h" + #include "rvl/GX.h" // IWYU pragma: export namespace EGG { class StateGX { public: + struct ScopedColor { + ScopedColor(bool x) { + old = GXSetColorUpdate_(x); + } - struct ScopedColor - { - ScopedColor(bool x) - { - old = GXSetColorUpdate_(x); - } + ~ScopedColor() { + GXSetColorUpdate_(old); + } - ~ScopedColor() - { - GXSetColorUpdate_(old); - } + bool old; + }; - bool old; - }; + struct ScopedAlpha { + ScopedAlpha(bool x) { + old = GXSetAlphaUpdate_(x); + } - struct ScopedAlpha - { - ScopedAlpha(bool x) - { - old = GXSetAlphaUpdate_(x); - } + ~ScopedAlpha() { + GXSetAlphaUpdate_(old); + } - ~ScopedAlpha() - { - GXSetAlphaUpdate_(old); - } + bool old; + }; - bool old; - }; + struct ScopedDither { + ScopedDither(bool x) { + old = GXSetDither_(x); + } - struct ScopedDither - { - ScopedDither(bool x) - { - old = GXSetDither_(x); - } + ~ScopedDither() { + GXSetDither_(old); + } - ~ScopedDither() - { - GXSetDither_(old); - } + bool old; + }; - bool old; - }; + struct CacheGX { + /* 0x00 */ u8 _0x00[0xC]; + /* 0x0C */ bool mDstAlphaEnable; + /* 0x0D */ u8 mDstAlpha; + /* 0x0E */ u8 _0x0E[0x18 - 0x0E]; + }; - static GXColor& getDefaultTexColor() { return sDefaultTexColor; } + struct MemLayout { + /* 0x00 */ int mLayout; + /* 0x04 */ u32 numRegions; + /* 0x08 */ GXTexRegion mRegions[10]; + }; + + static GXColor &getClearEfb() { + return s_clearEfb; + } static void initialize(u16, u16, GXColor, GXPixelFmt); static void frameInit(); - static void textureInit(); // Guess for 804b4810 + static void setTMemLayout(int layout); static void resetGX(); static void resetVtx(); @@ -72,33 +79,35 @@ public: static void resetGXCache(); - static void GXSetPixelFmt(GXPixelFmt pixelFmt, GXZFmt16 zFmt); - static void invalidateTexAllGX(); + static void GXSetPixelFmt_(GXPixelFmt pixelFmt, GXZFmt16 zFmt); static bool GXSetColorUpdate_(bool); static bool GXSetAlphaUpdate_(bool); static bool GXSetDither_(bool); - static bool GXSetDstAlpha_(bool, u8); - - static bool GXSetColorUpdate(bool); - static bool GXSetAlphaUpdate(bool); - static bool GXSetDither(); - static void GXCopyTex(void *data, bool); - static bool GXSetDstAlpha(); - // Unk func here - static void GXSetProjection(Mtx44, int); + static void GXCopyTex_(void *data, bool); + static CacheGX &GXSetDstAlpha_(bool, u8); + static void GXSetProjection_(Mtx44, GXProjectionType); static void GXSetProjectionv_(const f32 *); static void GXSetViewport_(f32, f32, f32, f32, f32, f32); static void GXSetScissor_(u32, u32, u32, u32); static void GXSetScissorBoxOffset_(s32, s32); + // not sure + static void CalculateScreenScissor(const f32 src[4], u32 dst[4]); - static u16 s_commandFlag; - static u16 s_flag; static u16 s_widthEfb; static u16 s_heightEfb; - static GXColor sDefaultTexColor; + static GXPixelFmt s_pixFormat; + static GXZFmt16 s_zFmt16; + static GXColor s_clearEfb; + static u16 s_flag; + static u16 s_commandFlag; + + static CacheGX s_cacheGX; + // Inofficial names + static GXTexObj sDefaultTexObj; + static MemLayout s_tmem_layout; // same name, different type }; } // namespace EGG diff --git a/include/rvl/GX/GXPixel.h b/include/rvl/GX/GXPixel.h index 044aa9a6..165ce4d9 100644 --- a/include/rvl/GX/GXPixel.h +++ b/include/rvl/GX/GXPixel.h @@ -17,11 +17,15 @@ void GXSetFog(GXFogType type, GXColor color, f32 start, f32 end, f32 near, f32 f void GXInitFogAdjTable(GXFogAdjTable *table, u16 width, const Mtx44 proj); void GXSetFogRangeAdj(GXBool enable, u16 center, const GXFogAdjTable *table); void GXSetBlendMode(GXBlendMode mode, GXBlendFactor src, GXBlendFactor dst, GXLogicOp op); +void GXGetColorUpdate(GXBool *enable); void GXSetColorUpdate(GXBool enable); +void GXGetAlphaUpdate(GXBool *enable); void GXSetAlphaUpdate(GXBool enable); void GXSetZMode(GXBool enableTest, GXCompare func, GXBool enableUpdate); void GXSetZCompLoc(GXBool beforeTex); +void GXGetPixelFmt(GXPixelFmt *pixelFmt, GXZFmt16 *zFmt); void GXSetPixelFmt(GXPixelFmt pixelFmt, GXZFmt16 zFmt); +void GXGetDither(GXBool *enable); void GXSetDither(GXBool enable); void GXSetDstAlpha(GXBool enable, u8 alpha); void GXSetFieldMask(GXBool enableEven, GXBool enableOdd); diff --git a/include/rvl/GX/GXTexture.h b/include/rvl/GX/GXTexture.h index fcce31ed..0b3c14dc 100644 --- a/include/rvl/GX/GXTexture.h +++ b/include/rvl/GX/GXTexture.h @@ -44,6 +44,9 @@ void GXGetTexObjLODAll( u8 *biasClampEnable, u8 *edgeLODEnable, GXAnisotropy *anisotropy ); +void GXSetTexCoordScaleManually(GXTexCoordID, GXBool, u16, u16); +void GXSetTexCoordBias(GXTexCoordID, GXBool, GXBool); + u16 GXGetTexObjWidth(const GXTexObj *obj); u16 GXGetTexObjHeight(const GXTexObj *obj); GXTexFmt GXGetTexObjFormat(const GXTexObj *obj); diff --git a/include/rvl/GX/GXTransform.h b/include/rvl/GX/GXTransform.h index bc571398..8ef9ecb5 100644 --- a/include/rvl/GX/GXTransform.h +++ b/include/rvl/GX/GXTransform.h @@ -33,7 +33,7 @@ void GXGetViewportv(f32 view[6]); void GXSetZScaleOffset(f32 scale, f32 offset); void GXSetScissor(u32 x, u32 y, u32 w, u32 h); void GXGetScissor(u32 *x, u32 *y, u32 *w, u32 *h); -void GXSetScissorBoxOffset(u32 ox, u32 oy); +void GXSetScissorBoxOffset(s32 ox, s32 oy); void GXSetClipMode(GXClipMode mode); void __GXSetProjection(void); diff --git a/src/egg/gfx/eggCapTexture.cpp b/src/egg/gfx/eggCapTexture.cpp index 9aee5996..1fc25133 100644 --- a/src/egg/gfx/eggCapTexture.cpp +++ b/src/egg/gfx/eggCapTexture.cpp @@ -40,7 +40,7 @@ void CapTexture::capture(u16 x, u16 y, bool upscale, int format) { GXSetZMode(true, GX_ALWAYS, (mCapFlags & 4) != 0); GXSetCopyClear(mClearColor, field_0x20); GXSetCopyClamp(3); - StateGX::GXCopyTex(dataPtr, true); + StateGX::GXCopyTex_(dataPtr, true); GXSetCopyFilter(0, copyArg2, 0, defaultFilter.values); if ((mCapFlags & 0x10) != 0) { diff --git a/src/egg/gfx/eggStateGX.cpp b/src/egg/gfx/eggStateGX.cpp index baf181f0..f364b81a 100644 --- a/src/egg/gfx/eggStateGX.cpp +++ b/src/egg/gfx/eggStateGX.cpp @@ -1,3 +1,323 @@ #include "egg/gfx/eggStateGX.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggDisplay.h" +#include "egg/core/eggSystem.h" +#include "nw4r/g3d/g3d_init.h" +#include "nw4r/g3d/platform/g3d_tmem.h" +#include "rvl/GX/GXAttr.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXFrameBuf.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXPixel.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" + +#include + +namespace { + +static GXTexRegion *texRegionCallback(const GXTexObj *pObj, GXTexMapID map) { + return &EGG::StateGX::s_tmem_layout.mRegions[map % EGG::StateGX::s_tmem_layout.numRegions]; +} + +static const GXColor white = {0xFF, 0xFF, 0xFF, 0xFF}; + +static const f32 identity[3][4] = { + {1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, +}; + +} // namespace + +namespace EGG { + +GXTexObj StateGX::sDefaultTexObj; +StateGX::MemLayout StateGX::s_tmem_layout; +StateGX::CacheGX StateGX::s_cacheGX; + +u16 StateGX::s_widthEfb; +u16 StateGX::s_heightEfb; +GXPixelFmt StateGX::s_pixFormat; +GXZFmt16 StateGX::s_zFmt16; +GXColor StateGX::s_clearEfb; +u16 StateGX::s_flag; +u16 StateGX::s_commandFlag; + +void StateGX::initialize(u16 width, u16 height, GXColor color, GXPixelFmt pixelFmt) { + s_widthEfb = width; + s_heightEfb = height; + s_clearEfb = color; + s_pixFormat = pixelFmt; + + if (BaseSystem::getDisplay() != nullptr) { + BaseSystem::getDisplay()->setClearColor(color); + } + + static u8 sDefaultTexObjData[16] = {0}; + + GXInitTexObj(&sDefaultTexObj, sDefaultTexObjData, 4, 4, GX_TF_IA8, GX_CLAMP, GX_CLAMP, 0); + GXInitTexObjLOD(&sDefaultTexObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1); + invalidateTexAllGX(); + frameInit(); + setTMemLayout(nw4r::g3d::tmem::TMEM_LAYOUT_1); +} + +void StateGX::frameInit() { + GXSetPixelFmt_(s_pixFormat, s_zFmt16); + if (BaseSystem::mConfigData->getDisplay() != nullptr) { + s_clearEfb = BaseSystem::mConfigData->getDisplay()->getClearColor(); + } + GXInvalidateVtxCache(); + GXSetCurrentMtx(0); + GXSetCoPlanar(false); + GXSetClipMode(GX_CLIP_ENABLE); + resetGX(); + nw4r::g3d::G3dReset(); +} + +void StateGX::setTMemLayout(int layout) { + s_tmem_layout.mLayout = layout; + if (nw4r::g3d::tmem::TMEM_LAYOUT_NONE <= layout && layout <= nw4r::g3d::tmem::TMEM_LAYOUT_3) { + nw4r::g3d::tmem::SetTMemLayout(static_cast(layout)); + s_tmem_layout.numRegions = 8; + } else { + static const u32 numbers[4] = {0x8, 0x4, 0x1, 0x7}; + static const u32 offsets[4] = {0x8000, 0x20000, 0x80000, 0}; + + u32 index = layout - 4; + s_tmem_layout.numRegions = numbers[index]; + for (u32 i = 0; i < 8; i++) { + std::memset(&s_tmem_layout.mRegions[i], 0, sizeof(GXTexRegion)); + } + + u32 addr = 0; + for (u32 i = 0; i < numbers[index]; i++) { + int u1 = layout == 7 ? (0 <= i && i < 3 ? 1 : 0) : index; + if ((i & 1) != 0) { + GXInitTexCacheRegion(&s_tmem_layout.mRegions[i], false, addr + 0x80000, u1, addr, u1); + } else { + GXInitTexCacheRegion(&s_tmem_layout.mRegions[i], false, addr, u1, addr + 0x80000, u1); + } + addr += offsets[u1]; + } + GXSetTexRegionCallback(texRegionCallback); + } +} + +void StateGX::resetGX() { + if ((s_flag & 1) == 0) { + resetVtx(); + resetIndirect(); + resetColorChannel(); + resetTexture(); + resetTexGen(); + resetTev(); + resetPE(); + } + resetGXCache(); +} + +void StateGX::resetVtx() { + 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); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX2, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX3, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX4, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX5, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX6, GX_CLR_RGBA, GX_RGBA4, 7); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX7, GX_CLR_RGBA, GX_RGBA4, 7); +} + +void StateGX::resetColorChannel() { + GXSetNumChans(1); + GXSetChanAmbColor(GX_COLOR0A0, white); + GXSetChanAmbColor(GX_COLOR1A1, white); + + GXSetChanMatColor(GX_COLOR0A0, white); + + GXSetChanMatColor(GX_COLOR1A1, white); + GXSetCullMode(GX_CULL_BACK); + GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); +} + +void StateGX::resetIndirect() { + GXSetNumIndStages(0); + static const f32 ind[2][3] = { + {0.5f, 0.0f, 0.0f}, + {0.0f, 0.5f, 0.0f}, + }; + for (u32 i = 0; i < 3; i++) { + GXSetIndTexMtx(static_cast(i + GX_ITM_0), ind, 1); + } + for (u32 i = 0; i < 4; i++) { + GXSetIndTexCoordScale(static_cast(i + GX_INDTEXSTAGE0), GX_ITS_1, GX_ITS_1); + } +} + +void StateGX::resetTexture() { + for (u32 i = 0; i < s_tmem_layout.numRegions; i++) { + GXLoadTexObj(&sDefaultTexObj, static_cast(i + GX_TEXMAP0)); + } +} + +void StateGX::resetTexGen() { + GXSetNumTexGens(1); + + for (u32 i = 0; i < 10; i++) { + GXLoadTexMtxImm(identity, i * 3 + 0x1E, GX_MTX_3x4); + } + + for (u32 i = 0; i < GX_MAX_TEXCOORD; i++) { + GXTexCoordID id = static_cast(i); + GXSetTexCoordGen2(id, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetTexCoordScaleManually(id, false, 0, 0); + GXSetTexCoordBias(id, false, false); + } +} + +void StateGX::resetTev() { + GXSetNumTevStages(1); + for (u32 i = 0; i < GX_MAX_TEVSTAGE; i++) { + GXTevStageID id = static_cast(i); + GXSetTevDirect(id); + GXSetTevOrder(id, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevColorIn(id, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO); + GXSetTevColorOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevSwapMode(id, GX_TEV_SWAP0, GX_TEV_SWAP0); + } + + for (u32 i = 0; i < GX_MAX_KCOLOR; i++) { + GXTevKColorID id = static_cast(i); + GXSetTevKColor(id, white); + } + + for (u32 i = 0; i < GX_MAX_TEVREG; i++) { + GXTevRegID id = static_cast(i); + GXSetTevColor(id, white); + } + + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA); +} + +void StateGX::resetPE() { + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + GXSetZTexture(0, GX_TF_Z24X8, 0); + GXSetZMode(true, GX_LEQUAL, true); + GXSetFog(GX_FOG_NONE, white, 0.0f, 1.0f, 0.1f, 1.0f); + GXSetFogRangeAdj(false, 0, nullptr); + GXSetZCompLoc(true); + GXSetDstAlpha(false, 0); +} + +void StateGX::resetGXCache() { + GXSetColorUpdate_(true); + GXSetAlphaUpdate_(true); + GXSetDither_(true); + GXSetDstAlpha_(false, 0); +} + +void StateGX::GXSetPixelFmt_(GXPixelFmt pixelFmt, GXZFmt16 zFmt) { + GXPixelFmt oldPixelFmt; + GXZFmt16 oldZFmt; + + GXGetPixelFmt(&oldPixelFmt, &oldZFmt); + if (pixelFmt != oldPixelFmt || zFmt != oldZFmt) { + GXBool oldColorUpdate; + GXGetColorUpdate(&oldColorUpdate); + bool bOldColorUpdate = oldColorUpdate; + GXBool oldAlphaUpdate; + GXGetAlphaUpdate(&oldAlphaUpdate); + bool bOldAlphaUpdate = oldAlphaUpdate; + + GXSetPixelFmt(pixelFmt, zFmt); + GXSetColorUpdate(bOldColorUpdate); + GXSetAlphaUpdate(bOldAlphaUpdate); + } +} + +void StateGX::invalidateTexAllGX() { + GXInvalidateTexAll(); +} + +bool StateGX::GXSetColorUpdate_(bool enable) { + GXBool oldEnable; + GXGetColorUpdate(&oldEnable); + bool bOldEnable = oldEnable; + GXSetColorUpdate(enable); + return bOldEnable; +} + +bool StateGX::GXSetAlphaUpdate_(bool enable) { + GXBool oldEnable; + GXGetAlphaUpdate(&oldEnable); + bool bOldEnable = oldEnable; + GXSetAlphaUpdate(enable); + return bOldEnable; +} + +bool StateGX::GXSetDither_(bool enable) { + GXBool oldEnable; + GXGetDither(&oldEnable); + bool bOldEnable = oldEnable; + GXSetDither(enable); + return bOldEnable; +} + +void StateGX::GXCopyTex_(void *data, bool bUpdate) { + GXCopyTex(data, bUpdate); +} + +StateGX::CacheGX &StateGX::GXSetDstAlpha_(bool enable, u8 alpha) { + GXSetDstAlpha(enable, alpha); + s_cacheGX.mDstAlphaEnable = enable; + s_cacheGX.mDstAlpha = alpha; + return s_cacheGX; +} + +void StateGX::CalculateScreenScissor(const f32 src[4], u32 dst[4]) { + dst[0] = src[0] >= 0.0f ? src[0] : 0.0f; + dst[1] = src[1] >= 0.0f ? src[1] : 0.0f; + dst[2] = dst[0] + src[2] > 640.0f ? 640 - dst[0] : src[2]; + dst[3] = dst[1] + src[3] > 528.0f ? 528 - dst[1] : src[3]; +} + +void StateGX::GXSetProjection_(Mtx44 proj, GXProjectionType type) { + GXSetProjection(proj, type); + s_commandFlag |= 1; +} + +void StateGX::GXSetProjectionv_(const f32 *proj) { + GXSetProjectionv(proj); + s_commandFlag |= 1; +} + +void StateGX::GXSetViewport_(f32 ox, f32 oy, f32 sx, f32 sy, f32 near, f32 far) { + GXSetViewport(ox, oy, sx, sy, near, far); + s_commandFlag |= 2; +} + +void StateGX::GXSetScissor_(u32 x, u32 y, u32 w, u32 h) { + GXSetScissor(x, y, w, h); + s_commandFlag |= 4; +} + +void StateGX::GXSetScissorBoxOffset_(s32 ox, s32 oy) { + GXSetScissorBoxOffset(ox, oy); + s_commandFlag |= 8; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggTextureBuffer.cpp b/src/egg/gfx/eggTextureBuffer.cpp index d8489705..c08f7f45 100644 --- a/src/egg/gfx/eggTextureBuffer.cpp +++ b/src/egg/gfx/eggTextureBuffer.cpp @@ -12,7 +12,7 @@ TextureBuffer::TextureBuffer() : mSize(0), mState(STATE_FREE), mpNext(nullptr), void TextureBuffer::configure() { CapTexture::configure(); - setClearColor(StateGX::getDefaultTexColor()); + setClearColor(StateGX::getClearEfb()); setWrap(GX_CLAMP, GX_CLAMP); setFilt(GX_LINEAR, GX_LINEAR); setPixModeSync(true); From 00ececa0b583cc7893d37898beab2d2ae3f36b7a Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Fri, 21 Mar 2025 19:38:30 -0400 Subject: [PATCH 26/62] Egg Camera a small bit closer --- include/egg/gfx/eggCamera.h | 23 +++++++++------ include/egg/math/eggRotation.h | 50 ++++++++++++++++++++++++++++++++ include/egg/math/eggVector.h | 26 +++++------------ src/egg/gfx/eggCamera.cpp | 53 ++++++++++++++++++++++++---------- 4 files changed, 109 insertions(+), 43 deletions(-) create mode 100644 include/egg/math/eggRotation.h diff --git a/include/egg/gfx/eggCamera.h b/include/egg/gfx/eggCamera.h index 220d91c7..c3104fb7 100644 --- a/include/egg/gfx/eggCamera.h +++ b/include/egg/gfx/eggCamera.h @@ -2,6 +2,7 @@ #define EGG_CAMERA_H #include "egg/math/eggMatrix.h" +#include "egg/math/eggRotation.h" #include "egg/math/eggVector.h" #include "nw4r/g3d/g3d_camera.h" @@ -10,7 +11,6 @@ namespace EGG { class BaseCamera { public: BaseCamera() {} - // Which way around? virtual Matrix34f &getViewMatrix() = 0; virtual const Matrix34f &getViewMatrix() const = 0; virtual void updateMatrix(); @@ -23,11 +23,18 @@ public: virtual Matrix34f &getViewMatrixOld() = 0; void setG3DCamera(nw4r::g3d::Camera &); + // Vector3f getRightVector(); + // Vector3f getLookVector(); + // Vector3f getUpVector(); + +protected: + /* 0x04 */ Matrix34f mViewMtx; + /* 0x34 */ Matrix34f mOtherMtx; }; class LookAtCamera : public BaseCamera { public: - LookAtCamera() : mPosition(0.0f, 10.0f, 0.0f), mRight(0.0f, 0.0f, 0.0f), mUp(0.0f, 1.0f, 0.0f) {} + LookAtCamera() : mPos(0.0f, 10.0f, 0.0f), mAt(0.0f, 0.0f, 0.0f), mUp(0.0f, 1.0f, 0.0f) {} // Which way around? virtual Matrix34f &getViewMatrix() override { return mViewMtx; @@ -40,17 +47,15 @@ public: virtual void loadMatrix() override; virtual void loadOldMatrix() override; virtual EGG::Vector3f getPosition() override { - return mPosition; + return mPos; } virtual void doDraw() override; virtual Matrix34f &getViewMatrixOld() override; protected: - /* 0x04 */ Matrix34f mViewMtx; - /* 0x34 */ Matrix34f mOtherMtx; - /* 0x64 */ Vector3f mPosition; - /* 0x70 */ Vector3f mRight; + /* 0x64 */ Vector3f mPos; + /* 0x70 */ Vector3f mAt; /* 0x7C */ Vector3f mUp; }; @@ -63,8 +68,8 @@ public: private: void update_parms(); - /* 0x88 */ f32 field_0x88; - /* 0x8C */ f32 field_0x8C; + /* 0x88 */ EGG::Rotation field_0x88; + /* 0x8C */ EGG::Rotation field_0x8C; }; } // namespace EGG diff --git a/include/egg/math/eggRotation.h b/include/egg/math/eggRotation.h new file mode 100644 index 00000000..97910e97 --- /dev/null +++ b/include/egg/math/eggRotation.h @@ -0,0 +1,50 @@ +#ifndef EGG_ROTATION_H +#define EGG_ROTATION_H + +#include "egg/math/eggMath.h" + +namespace EGG { + +template +struct Rotation { + Rotation() {} + Rotation(T val) : mRot(val) {} + Rotation(const Rotation &other) { + mRot = other.mRot; + } + Rotation &operator=(const Rotation &other) { + mRot = val; + return *this; + } + Rotation &operator=(T val) { + mRot = val; + return *this; + } + + operator T() const { + return mRot; + } + + Rotation &operator-=(T val) { + mRot -= val; + return *this; + } + Rotation &operator+=(T val) { + mRot -= val; + return *this; + } + + const T cos() const { + return Math::cos(*this); + } + const T sin() const { + return Math::sin(*this); + } + +protected: + T mRot; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/math/eggVector.h b/include/egg/math/eggVector.h index b0ac18c4..3fa0c871 100644 --- a/include/egg/math/eggVector.h +++ b/include/egg/math/eggVector.h @@ -3,25 +3,19 @@ #include "common.h" #include "egg/math/eggMath.h" + #include "nw4r/math.h" namespace EGG { struct Vector3f : public nw4r::math::VEC3 { - // __ct__Q23EGG8Vector3fFv Vector3f() : nw4r::math::VEC3() {} - - // __ct__Q23EGG8Vector3fFfff Vector3f(f32 fx, f32 fy, f32 fz) : VEC3(fx, fy, fz) {} - // ~Vector3f() {} - - // __cl__Q23EGG8Vector3fFi f32 &operator()(int i) { return ((f32 *)this)[i]; } - // __ml__Q23EGG8Vector3fCFf Vector3f operator*(f32 f) const { return Vector3f(x * f, y * f, z * f); } @@ -30,12 +24,10 @@ struct Vector3f : public nw4r::math::VEC3 { return Vector3f(v.x * f, v.y * f, v.z * f); } - // __pl__Q23EGG8Vector3fCFRCQ23EGG8Vector3f Vector3f operator+(const Vector3f &v) const { return Vector3f(x + v.x, y + v.y, z + v.z); } - // __apl__Q23EGG8Vector3fFRCQ23EGG8Vector3f Vector3f &operator+=(const Vector3f &v) { x += v.x; y += v.y; @@ -43,7 +35,6 @@ struct Vector3f : public nw4r::math::VEC3 { return *this; } - // __mi__Q23EGG8Vector3fCFv Vector3f operator-() const { f32 z = this->z; f32 y = this->y; @@ -51,12 +42,10 @@ struct Vector3f : public nw4r::math::VEC3 { return Vector3f(-x, -y, -z); } - // __mi__Q23EGG8Vector3fCFRCQ23EGG8Vector3f Vector3f operator-(const Vector3f &v) { return Vector3f(x - v.x, y - v.y, z - v.z); } - // __ami__Q23EGG8Vector3fFRCQ23EGG8Vector3f Vector3f &operator-=(const Vector3f &v) { x -= v.x; y -= v.y; @@ -64,24 +53,20 @@ struct Vector3f : public nw4r::math::VEC3 { return *this; } - // __amu__Q23EGG8Vector3fFf Vector3f &operator*=(f32 f) { multScalar(f); return *this; } - // __dv__Q23EGG8Vector3fCFf Vector3f operator/(f32 f) const { return Vector3f(x / f, y / f, z / f); } - // __adv__Q23EGG8Vector3fCFf // assumed Vector3f &operator/=(f32 f) { divScalar(f); return *this; } - // __ne__Q23EGG8Vector3fCFRCQ23EGG8Vector3f bool operator!=(const Vector3f &v) { return x != v.x || y != v.y || z != v.z; } @@ -101,12 +86,10 @@ struct Vector3f : public nw4r::math::VEC3 { return EGG::Math::abs(EGG::Math::atan2(b, a)); } - // dot__Q23EGG8Vector3fCFRCQ23EGG8Vector3f f32 dot(const Vector3f &v) const { return x * v.x + y * v.y + z * v.z; } - // cross__Q23EGG8Vector3fCFRCQ23EGG8Vector3f Vector3f cross(const Vector3f &b) const { f32 _x = (y * b.z) - (z * b.y); f32 _y = (z * b.x) - (x * b.z); @@ -126,6 +109,13 @@ struct Vector3f : public nw4r::math::VEC3 { } f32 normalise(); + + Vector3f normalize() { + Vector3f other(x, y, z); + other.normalise(); + return other; + } + f32 setLength(const Vector3f &src, f32 len); f32 setLength(f32 len); diff --git a/src/egg/gfx/eggCamera.cpp b/src/egg/gfx/eggCamera.cpp index 77679d91..ed474b66 100644 --- a/src/egg/gfx/eggCamera.cpp +++ b/src/egg/gfx/eggCamera.cpp @@ -12,7 +12,7 @@ void BaseCamera::updateMatrix() { doUpdateMatrix(); } -void EGG::BaseCamera::draw(EGG::BaseCamera *cam) { +void BaseCamera::draw(EGG::BaseCamera *cam) { cam->loadMatrix(); doDraw(); } @@ -27,21 +27,37 @@ Matrix34f &LookAtCamera::getViewMatrixOld() { void LookAtCamera::doUpdateMatrix() { // NONMATCHING - mOtherMtx.copyFrom(mViewMtx); - EGG::Vector3f posRight = mPosition; - posRight -= mRight; - posRight.normalise(); - EGG::Vector3f forward = posRight.cross(mUp); - forward.normalise(); + mOtherMtx = mViewMtx; - EGG::Vector3f up = posRight.cross(forward); + Vector3f right(mPos); + + right -= mAt; + right.normalise(); + + Vector3f forward(mUp.cross(right).normalize()); + + Vector3f up(right.cross(forward)); up.normalise(); - mViewMtx.setTranslation(Vector3f((forward.dot(mPosition)), (up.dot(mPosition)), (posRight.dot(mPosition)))); - mViewMtx.setBase(0, forward); - mViewMtx.setBase(1, up); - mViewMtx.setBase(2, posRight); + f32 tx = -forward.dot(mPos); + f32 ty = -up.dot(mPos); + f32 tz = -right.dot(mPos); + + mViewMtx(0, 0) = forward(0); + mViewMtx(0, 1) = forward(1); + mViewMtx(0, 2) = forward(2); + mViewMtx(0, 3) = tx; + + mViewMtx(1, 0) = up(0); + mViewMtx(1, 1) = up(1); + mViewMtx(1, 2) = up(2); + mViewMtx(1, 3) = ty; + + mViewMtx(2, 0) = right(0); + mViewMtx(2, 1) = right(1); + mViewMtx(2, 2) = right(2); + mViewMtx(2, 3) = tz; } void LookAtCamera::doDraw() {} @@ -64,10 +80,15 @@ OrthoCamera::OrthoCamera() { void OrthoCamera::update_parms() { // NONMATCHING f32 z = field_0x8C; - f32 sin = Math::sin(field_0x88); - f32 cos = Math::cos(field_0x88); - mPosition.set(mRight.x, mRight.y, z); - mUp.set(sin, cos, 0.0f); + f32 sin = field_0x88.sin(); + f32 cos = field_0x88.cos(); + + mPos(2) = z; + mPos(1) = mAt(1); + mPos(0) = mAt(0); + mUp(2) = 0.f; + mUp(1) = cos; + mUp(0) = sin; } void OrthoCamera::doUpdateMatrix() { From 3c90e916b962f54a25d9cf4d404675a819ff3c1b Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 22 Mar 2025 01:10:41 +0100 Subject: [PATCH 27/62] Start LightObject --- config/SOUE01/splits.txt | 6 + config/SOUE01/symbols.txt | 13 +- include/egg/gfx/eggLightObject.h | 81 +++++++++++ src/egg/gfx/eggLightObject.cpp | 228 ++++++++++++++++++++++++++++++- 4 files changed, 320 insertions(+), 8 deletions(-) create mode 100644 include/egg/gfx/eggLightObject.h diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index b49f39fb..89d33489 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2256,6 +2256,9 @@ egg/gfx/eggLightManager.cpp: egg/gfx/eggLightObject.cpp: .text start:0x804A9810 end:0x804AB24C + .rodata start:0x804FBC88 end:0x804FBC98 + .data start:0x8056F098 end:0x8056F0B8 + .sdata2 start:0x8057F690 end:0x8057F6C0 egg/gfx/eggLightTexture.cpp: .text start:0x804AB250 end:0x804AD448 @@ -2332,6 +2335,9 @@ egg/gfx/eggScreenEffectBlur.cpp: egg/gfx/eggStateEfb.cpp: .text start:0x804B3DA0 end:0x804B460C + .sdata start:0x80574F60 end:0x80574F68 + .sbss start:0x80576898 end:0x805768A0 + .bss start:0x80675010 end:0x806750A0 egg/gfx/eggStateGX.cpp: .text start:0x804B4610 end:0x804B53EC diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 4668d25d..e68b3879 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26625,10 +26625,10 @@ FUN_804aa2c0 = .text:0x804AA2C0; // type:function size:0x9C FUN_804aa360 = .text:0x804AA360; // type:function size:0x168 FUN_804aa4d0 = .text:0x804AA4D0; // type:function size:0xA8 CalcDirDist__Q23EGG11LightObjectFv = .text:0x804AA580; // type:function size:0xD4 -FUN_804aa660 = .text:0x804AA660; // type:function size:0x44 +CalcAt__Q23EGG11LightObjectFv = .text:0x804AA660; // type:function size:0x44 SetPos__Q23EGG11LightObjectFRCQ34nw4r4math4VEC3 = .text:0x804AA6B0; // type:function size:0x1C SetAt__Q23EGG11LightObjectFRCQ34nw4r4math4VEC3 = .text:0x804AA6D0; // type:function size:0x1C -FUN_804aa6f0 = .text:0x804AA6F0; // type:function size:0x8 +SetDist__Q23EGG11LightObjectFf = .text:0x804AA6F0; // type:function size:0x8 SetPosAt__Q23EGG11LightObjectFRCQ34nw4r4math4VEC3RCQ34nw4r4math4VEC3 = .text:0x804AA700; // type:function size:0x34 SetBinaryInner__Q23EGG11LightObjectFRCQ33EGG28IBinary3Bin = .text:0x804AA740; // type:function size:0x418 GetBinaryInner__Q23EGG11LightObjectCFPQ33EGG28IBinary3Bin = .text:0x804AAB60; // type:function size:0xF4 @@ -29166,7 +29166,7 @@ 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 -lbl_804FBC88 = .rodata:0x804FBC88; // type:object size:0x10 data:float +zeroVec__3EGG = .rodata:0x804FBC88; // type:object size:0xC data:float lbl_804FBC98 = .rodata:0x804FBC98; // type:object size:0xC data:4byte lbl_804FBCA4 = .rodata:0x804FBCA4; // type:object size:0xC data:4byte lbl_804FBCB0 = .rodata:0x804FBCB0; // type:object size:0x10 data:4byte @@ -37370,7 +37370,7 @@ __vt__Q23EGG7Frustum = .data:0x8056F030; // type:object size:0x14 EGG__GfxEnginer__Configuration__vtable = .data:0x8056F048; // type:object size:0x10 __vt__Q23EGG8IScnProc = .data:0x8056F058; // type:object size:0x10 EGG__LightManager__vtable = .data:0x8056F068; // type:object size:0x30 -EGG__LightObject__vtable = .data:0x8056F098; // type:object size:0x20 +__vt__Q23EGG11LightObject = .data:0x8056F098; // type:object size:0x20 __vt__Q23EGG12LightTexture = .data:0x8056F0B8; // type:object size:0x38 __vt__Q23EGG19LightTextureManager = .data:0x8056F0F0; // type:object size:0x1C lbl_8056F110 = .data:0x8056F110; // type:object size:0x9 data:string @@ -41179,7 +41179,7 @@ spChangeTVModeFuncInfo__Q23EGG6Screen = .sbss:0x8057687C; // type:object size:0x sCanvasScale__Q23EGG6Screen = .sbss:0x80576880; // type:object size:0x8 data:float sCanvasOffset__Q23EGG6Screen = .sbss:0x80576888; // type:object size:0x8 data:float @GUARD@Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen@defaultRoot = .sbss:0x80576890; // type:object size:0x1 data:byte -lbl_80576898 = .sbss:0x80576898; // type:object size:0x8 data:4byte +sPushCount__Q23EGG8StateEfb = .sbss:0x80576898; // type:object size:0x4 data:4byte s_widthEfb__Q23EGG7StateGX = .sbss:0x805768A0; // type:object size:0x2 data:2byte s_heightEfb__Q23EGG7StateGX = .sbss:0x805768A2; // type:object size:0x2 data:2byte s_pixFormat__Q23EGG7StateGX = .sbss:0x805768A4; // type:object size:0x4 data:4byte @@ -49807,7 +49807,8 @@ lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0xC data:float @LOCAL@Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen@defaultRoot = .bss:0x80674F00; // type:object size:0x88 data:4byte sScreen__Q23EGG16ScreenEffectBase = .bss:0x80674F88; // type:object size:0x88 lbl_80675010 = .bss:0x80675010; // type:object size:0x30 -lbl_80675040 = .bss:0x80675040; // type:object size:0x18 data:float +lbl_80675040 = .bss:0x80675040; // type:object size:0x14 data:float +lbl_80675054 = .bss:0x80675054; // type:object size:0x4 data:float lbl_80675058 = .bss:0x80675058; // type:object size:0x18 data:float lbl_80675070 = .bss:0x80675070; // type:object size:0x30 data:float sDefaultTexObj__Q23EGG7StateGX = .bss:0x806750A0; // type:object size:0x20 diff --git a/include/egg/gfx/eggLightObject.h b/include/egg/gfx/eggLightObject.h new file mode 100644 index 00000000..84fbdcf3 --- /dev/null +++ b/include/egg/gfx/eggLightObject.h @@ -0,0 +1,81 @@ +#ifndef EGG_LIGHT_OBJ_H +#define EGG_LIGHT_OBJ_H + +#include "egg/math/eggVector.h" +#include "egg/prim/eggBinary.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class LightObject : public IBinary { +public: + struct BinData {}; + LightObject(); + virtual ~LightObject() {} + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + + void CalcDirDist(); + void Reset(); + void Calc(); + void CalcView(nw4r::math::MTX34 const &); + void InitGX(GXLightObj *obj) const; + + void CalcAt(); + void SetPos(const nw4r::math::VEC3 &); + void SetAt(const nw4r::math::VEC3 &); + void SetPosAt(nw4r::math::VEC3 const &, nw4r::math::VEC3 const &); + void SetDist(f32); + + int getField0x3C() const { + return field_0x3C; + } + + GXSpotFn getSpotFn() const { + return static_cast(mSpotFn); + } + + GXDistAttnFn getDistAttnFn() const { + return static_cast(mDistAttnFn); + } + + f32 getDistance() const { + return mDist; + } + +private: + /* 0x04 */ u16 mIndex; + /* 0x06 */ u16 field_0x06; + /* 0x08 */ nw4r::math::VEC3 mAt; + /* 0x14 */ nw4r::math::VEC3 mPos; + /* 0x20 */ nw4r::math::VEC3 mDir; + /* 0x2C */ GXColor mWhite; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ f32 mDist; + /* 0x38 */ GXColor mBlack; + /* 0x3C */ u8 field_0x3C; + /* 0x3D */ u8 field_0x3D; + /* 0x3E */ u8 mSpotFn; + /* 0x3F */ u8 mDistAttnFn; + /* 0x40 */ f32 field_0x40; + /* 0x44 */ f32 field_0x44; + /* 0x48 */ f32 field_0x48; + /* 0x4C */ nw4r::math::VEC3 field_0x4C; + /* 0x58 */ nw4r::math::VEC3 field_0x58; + /* 0x64 */ f32 field_0x64; + /* 0x68 */ u16 field_0x68; + /* 0x6C */ nw4r::math::VEC3 field_0x6C; + /* 0x78 */ GXColor field_0x78; + /* 0x7C */ nw4r::math::VEC3 field_0x7C; + /* 0x88 */ nw4r::math::VEC3 field_0x88; + /* 0x94 */ nw4r::math::VEC3 field_0x94; + /* 0xA0 */ u16 field_0xA0; +}; + +} // namespace EGG + +#endif diff --git a/src/egg/gfx/eggLightObject.cpp b/src/egg/gfx/eggLightObject.cpp index c842a6ec..9eb4db95 100644 --- a/src/egg/gfx/eggLightObject.cpp +++ b/src/egg/gfx/eggLightObject.cpp @@ -1,3 +1,227 @@ -#include "egg/gfx/eggLight.h" +#include "egg/gfx/eggLightObject.h" -namespace EGG {} // namespace EGG +#include "egg/gfx/eggDrawGX.h" +#include "nw4r/math/math_arithmetic.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtxvec.h" +#include "rvl/MTX/vec.h" + +namespace EGG { + +template <> +const char *IBinary::GetBinaryType() { + return "LOBJ"; +} + +template <> +int IBinary::GetVersion() { + return 2; +} + +// why +static const f32 zeroVec[3] = {0.0f, 0.0f, 0.0f}; + +LightObject::LightObject() + : mIndex(0), + field_0x06(0), + mAt(zeroVec), + mPos(-10000.0f, 10000.0f, 10000.0f), + mDir(0.0f, -1.0f, 0.0f), + mWhite(DrawGX::WHITE), + field_0x30(1.0f), + mDist(1.0f), + mBlack(DrawGX::BLACK), + field_0x3C(0), + field_0x3D(1), + mSpotFn(0), + mDistAttnFn(0), + field_0x40(90.0f), + field_0x44(0.5f), + field_0x48(0.5f), + field_0x64(16.0f), + field_0x68(0x661) {} + +void LightObject::Reset() { + SetPosAt(nw4r::math::VEC3(-10000.0f, 10000.0f, 10000.0f), zeroVec); + field_0x68 = 0x661; + mWhite = DrawGX::WHITE; + mBlack = DrawGX::BLACK; + field_0x30 = 1.0; + field_0x3C = 0; + field_0x3D = 1; + field_0x40 = 90.0; + field_0x44 = 0.5; + field_0x48 = 0.5; + mSpotFn = 0; + mDistAttnFn = 0; + field_0x64 = 16.0; + field_0x58.x = 1.0; + field_0x4C.x = 1.0; + field_0x58.z = 0.0; + field_0x4C.y = 0.0; + field_0x58.y = 0.0; + field_0x4C.z = 0.0; +} + +void LightObject::Calc() { + field_0x6C = mDir; + field_0x78 = mWhite; +} + +void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) { + if ((field_0x68 & 1) == 0) { + return; + } + + if (getField0x3C() < 0 || getField0x3C() > 1) { + switch (getField0x3C()) { + case 3: { + // Halp + f32 scale = -1.0f; + field_0x88.x = 0.0f; + field_0x94.x = 0.0f; + field_0x88.y = 0.0f; + field_0x94.y = 0.0f; + field_0x94.z = -1.0f; + field_0x88.z = scale * mDist; + field_0x7C.z = 0.0f; + field_0x7C.y = 0.0f; + field_0x7C.x = 0.0f; + break; + } + case 4: { + // Halp + f32 scale = 1.0f; + field_0x7C.x = 0.0f; + field_0x94.x = 0.0f; + field_0x7C.y = 0.0f; + field_0x94.y = 0.0f; + field_0x94.z = 1.0f; + field_0x7C.z = scale * mDist; + field_0x88.z = 0.0f; + field_0x88.y = 0.0f; + field_0x88.x = 0.0f; + break; + } + case 2: + field_0x94 = mDir; + field_0x88 = mAt; + field_0x7C = mPos; + break; + } + + } else { + if (getField0x3C() == 1) { + nw4r::math::VEC3 tmp(-viewMtx._20, -viewMtx._21, -viewMtx._22); + if (PSVECMag(tmp) > 0.0f) { + nw4r::math::VEC3 angle; + C_VECHalfAngle(mDir, tmp, angle); + nw4r::math::VEC3Scale(&field_0x6C, &angle, -1.0f); + PSVECNormalize(field_0x6C, field_0x6C); + } else { + field_0x6C.y = 0.0f; + field_0x6C.x = 0.0f; + field_0x6C.z = 1.0f; + } + } + PSMTXMultVec(viewMtx, mPos, field_0x7C); + PSMTXMultVec(viewMtx, mAt, field_0x88); + nw4r::math::VEC3TransformNormal(&field_0x94, &viewMtx, &field_0x6C); + } +} + +void LightObject::InitGX(GXLightObj *obj) const { + if ((field_0x68 & 1) != 0 && ((field_0x68 >> 6) & 1) != 0) { + GXInitLightColor(obj, field_0x78); + switch (field_0x3D) { + case 1: { + nw4r::math::VEC3 tmp = field_0x94 * -1e10f; + GXInitLightPos(obj, tmp.x, tmp.y, tmp.z); + GXInitLightDir(obj, zeroVec[0], zeroVec[1], zeroVec[2]); + break; + } + case 0: { + GXInitLightPos(obj, field_0x7C.x, field_0x7C.y, field_0x7C.z); + GXInitLightDir(obj, zeroVec[0], zeroVec[1], zeroVec[2]); + break; + } + case 2: { + GXInitLightPos(obj, field_0x7C.x, field_0x7C.y, field_0x7C.z); + GXInitLightDir(obj, field_0x94.x, field_0x94.y, field_0x94.z); + break; + } + } + + if ((field_0x68 & 0x80) != 0) { + GXInitLightAttnA(obj, field_0x4C.x, field_0x4C.y, field_0x4C.z); + } else { + GXInitLightSpot(obj, field_0x40 > 0.0f ? field_0x40 : 0.0001f, getSpotFn()); + } + + if ((field_0x68 & 0x100) != 0) { + GXInitLightAttnK(obj, field_0x58.x, field_0x58.y, field_0x58.z); + } else { + GXInitLightDistAttn(obj, field_0x44 * getDistance(), field_0x48, getDistAttnFn()); + } + + if ((field_0x68 & 0x800) != 0) { + f32 ka = field_0x64 / 2.0f; + GXInitLightAttn(obj, 0.0f, 0.0f, 1.0f, ka, 0.0f, 1.0f - ka); + } + + } else { + GXInitLightColor(obj, DrawGX::BLACK); + } +} + +void LightObject::CalcDirDist() { + mDir.x = mAt.x - mPos.x; + mDir.y = mAt.y - mPos.y; + mDir.z = mAt.z - mPos.z; + mDist = nw4r::math::VEC3LenSq(&mDir); + if (mDist > 0.0f) { + nw4r::math::VEC3Scale(&mDir, &mDir, 1.0f / nw4r::math::FSqrt(mDist)); + } else { + mDir.z = 0.0f; + mDir.y = 0.0f; + mDir.x = 0.0f; + } +} + +void LightObject::CalcAt() { + mAt.x = mPos.x + mDir.x * mDist; + mAt.y = mPos.y + mDir.y * mDist; + mAt.z = mPos.z + mDir.z * mDist; +} + +void LightObject::SetPos(const nw4r::math::VEC3 &pos) { + mPos = pos; + CalcDirDist(); +} + +void LightObject::SetAt(const nw4r::math::VEC3 &at) { + mAt = at; + CalcDirDist(); +} + +void LightObject::SetDist(f32 dist) { + mDist = dist; + CalcAt(); +} + +void LightObject::SetPosAt(nw4r::math::VEC3 const &pos, nw4r::math::VEC3 const &at) { + mPos = pos; + mAt = at; + CalcDirDist(); +} + + +void LightObject::SetBinaryInner(const Bin &bin) {} + +void LightObject::GetBinaryInner(Bin *bin) const {} + +void LightObject::SetBinaryInner(const Bin &bin1, const Bin &bin2, f32 blend) {} + +} // namespace EGG From 818e818b56af7584c2f9b8274f68a2ff664605e3 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Fri, 21 Mar 2025 21:09:54 -0400 Subject: [PATCH 28/62] eggPalette and eggTexture --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 2 +- configure.py | 6 +- include/egg/gfx/eggPalette.h | 56 ++++++++++++++- include/egg/gfx/eggTexture.h | 115 ++++++++++++++++++++++++++++++- include/nw4r/lyt/lyt_texMap.h | 4 +- include/rvl/GX/GXTexture.h | 2 +- src/egg/gfx/eggPalette.cpp | 22 +++++- src/egg/gfx/eggTexture.cpp | 118 +++++++++++++++++++++++++++++++- src/nw4r/g3d/g3d_anmtexpat.cpp | 5 +- src/nw4r/g3d/res/g3d_resmat.cpp | 4 +- src/nw4r/lyt/lyt_texMap.cpp | 4 +- 12 files changed, 319 insertions(+), 20 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 89d33489..65ba25c3 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2175,6 +2175,7 @@ egg/gfx/eggPalette.cpp: egg/gfx/eggTexture.cpp: .text start:0x8049CB50 end:0x8049CFE4 + .sdata2 start:0x8057F3C8 end:0x8057F3E0 egg/gfx/eggAnalizeDL.cpp: .text start:0x8049CFF0 end:0x8049D7C0 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index e68b3879..9e8abbca 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26420,7 +26420,7 @@ load__Q23EGG7PaletteFv = .text:0x8049CB00; // type:function size:0x44 __dt__Q23EGG7TextureFv = .text:0x8049CB50; // type:function size:0x78 storeTIMG__Q23EGG7TextureFPCQ23EGG7ResTIMGUc = .text:0x8049CBD0; // type:function size:0x184 attachPalette__Q23EGG7TextureFPQ23EGG7Palette = .text:0x8049CD60; // type:function size:0x40 -initTexObj__Q23EGG7TextureFvl = .text:0x8049CDA0; // type:function size:0xF0 +initTexObj__Q23EGG7TextureFv = .text:0x8049CDA0; // type:function size:0xF0 initTexObj__Q23EGG7TextureF7_GXTlut = .text:0x8049CE90; // type:function size:0xF8 load__Q23EGG7TextureF11_GXTexMapID = .text:0x8049CF90; // type:function size:0x54 FUN_8049cff0 = .text:0x8049CFF0; // type:function size:0x12C diff --git a/configure.py b/configure.py index a03f64c2..c41aa5db 100644 --- a/configure.py +++ b/configure.py @@ -866,8 +866,8 @@ config.libs = [ "gfx", [ Object(NonMatching, "egg/gfx/eggCamera.cpp"), - Object(NonMatching, "egg/gfx/eggPalette.cpp"), - Object(NonMatching, "egg/gfx/eggTexture.cpp"), + Object(Matching, "egg/gfx/eggPalette.cpp"), + Object(Matching, "egg/gfx/eggTexture.cpp"), Object(NonMatching, "egg/gfx/eggUnk1.cpp"), # Unknown Object(Matching, "egg/gfx/eggCapTexture.cpp"), Object(NonMatching, "egg/gfx/eggCpuTexture.cpp"), @@ -879,7 +879,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggFog.cpp"), Object(NonMatching, "egg/gfx/eggFogManager.cpp"), Object(NonMatching, "egg/gfx/eggFrustum.cpp"), - Object(NonMatching, "egg/gfx/eggG3DUtility.cpp"), # Unknown Guess + Object(NonMatching, "egg/gfx/eggG3DUtility.cpp"), Object(NonMatching, "egg/gfx/eggGfxEngine.cpp"), Object(Matching, "egg/gfx/eggGlobalDrawState.cpp"), Object(NonMatching, "egg/gfx/eggGXUtility.cpp"), diff --git a/include/egg/gfx/eggPalette.h b/include/egg/gfx/eggPalette.h index a7677d52..ddfff217 100644 --- a/include/egg/gfx/eggPalette.h +++ b/include/egg/gfx/eggPalette.h @@ -1,6 +1,60 @@ #ifndef EGG_PALETTE_H #define EGG_PALETTE_H -namespace EGG {} // namespace EGG +#include "common.h" +#include "rvl/GX/GXTexture.h" + +namespace EGG { + +enum JUTTransparency { + UNK0, + UNK1 +}; +struct ResTLUT { + u8 format; + u8 transparency; + u16 numColors; +}; + +class Palette { +public: + Palette(GXTlut p1, GXTlutFmt p2, JUTTransparency p3, u16 p4, void *p5) { + storeTLUT(p1, p2, p3, p4, p5); + } + + Palette(GXTlut tlutNo, ResTLUT *p_tlutRes) { + storeTLUT(tlutNo, p_tlutRes); + } + + void storeTLUT(GXTlut, ResTLUT *); + void storeTLUT(GXTlut, GXTlutFmt, JUTTransparency, u16, void *); + bool load(); + + u8 getTlutName() const { + return mTlutName; + } + u8 getFormat() const { + return mFormat; + } + u8 getTransparency() const { + return mTransparency; + } + u16 getNumColors() const { + return mNumColors; + } + ResTLUT *getColorTable() const { + return mColorTable; + } + +private: + /* 0x00 */ GXTlutObj mTlutObj; + /* 0x0C */ u8 mTlutName; + /* 0x0D */ u8 mFormat; + /* 0x10 */ ResTLUT *mColorTable; + /* 0x14 */ u16 mNumColors; + /* 0x16 */ u8 mTransparency; +}; + +} // namespace EGG #endif diff --git a/include/egg/gfx/eggTexture.h b/include/egg/gfx/eggTexture.h index dcf0e926..e166b882 100644 --- a/include/egg/gfx/eggTexture.h +++ b/include/egg/gfx/eggTexture.h @@ -1,10 +1,121 @@ #ifndef EGG_TEXTURE_H #define EGG_TEXTURE_H +#include "common.h" +#include "egg/core/eggHeap.h" +#include "egg/gfx/eggPalette.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" namespace EGG { -// TODO: Implement Members -struct ResTIMG {}; +// Copy of ResTIMG from JUTTexture +struct ResTIMG { + /* 0x00 */ u8 format; + /* 0x01 */ u8 alphaEnabled; + /* 0x02 */ u16 width; + /* 0x04 */ u16 height; + /* 0x06 */ u8 wrapS; + /* 0x07 */ u8 wrapT; + /* 0x08 */ u8 indexTexture; + /* 0x09 */ u8 colorFormat; + /* 0x0A */ u16 numColors; + /* 0x0C */ u32 paletteOffset; + /* 0x10 */ u8 mipmapEnabled; + /* 0x11 */ u8 doEdgeLOD; + /* 0x12 */ u8 biasClamp; + /* 0x13 */ u8 maxAnisotropy; + /* 0x14 */ u8 minFilter; + /* 0x15 */ u8 magFilter; + /* 0x16 */ s8 minLOD; + /* 0x17 */ s8 maxLOD; + /* 0x18 */ u8 mipmapCount; + /* 0x19 */ u8 unknown; + /* 0x1A */ s16 LODBias; + /* 0x1C */ u32 imageOffset; +}; + +class Texture { +public: + Texture() { + setCaptureFlag(false); + mEmbPalette = NULL; + mTexInfo = NULL; + } + + Texture(const ResTIMG *p_timg, u8 param_1) { + mEmbPalette = NULL; + storeTIMG(p_timg, param_1); + setCaptureFlag(false); + } + + Texture(int, int, GXTexFmt, Heap *); + ~Texture(); + + void storeTIMG(ResTIMG const *pTIMG, u8 param0); + void storeTIMG(ResTIMG const *pTIMG, Palette *pPalette); + void storeTIMG(ResTIMG const *pTIMG, Palette *pPalette, GXTlut tlut); + void attachPalette(Palette *pPalette); + void init(); + void initTexObj(); + void initTexObj(GXTlut tlut); + void load(GXTexMapID texMapId); + void capture(int, int, GXTexFmt, bool, u8); + void captureTexture(int, int, int, int, bool, GXTexFmt, GXTexFmt); + void captureDolTexture(int, int, int, int, bool, GXTexFmt); + + const ResTIMG *getTexInfo() const { + return mTexInfo; + } + u8 getFormat() const { + return mTexInfo->format; + } + s32 getTransparency() { + return mTexInfo->alphaEnabled; + } + s32 getWidth() const { + return mTexInfo->width; + } + s32 getHeight() const { + return mTexInfo->height; + } + void setCaptureFlag(bool flag) { + mFlags &= 2 | flag; + } + u8 getCaptureFlag() const { + return mFlags & 1; + } + u8 getEmbPaletteDelFlag() const { + return mFlags & 2; + } + void setEmbPaletteDelFlag(bool flag) { + mFlags = (mFlags & 1) | (flag << 1); + } + bool operator==(const Texture &other) { + return mTexInfo == other.mTexInfo && mpPalette == other.mpPalette && mWrapS == other.mWrapS && + mWrapT == other.mWrapT && mMinFilter == other.mMinFilter && mMagFilter == other.mMagFilter && + mMinLOD == other.mMinLOD && mMinLOD == other.mMinLOD && mLODBias == other.mLODBias; + } + bool operator!=(const Texture &other) { + return !operator==(other); + } + +private: + /* 0x00 */ GXTexObj mTexObj; + /* 0x20 */ const ResTIMG *mTexInfo; + /* 0x24 */ void *mTexData; + /* 0x28 */ Palette *mEmbPalette; + /* 0x2C */ Palette *mpPalette; + /* 0x30 */ u8 mWrapS; + /* 0x31 */ u8 mWrapT; + /* 0x32 */ u8 mMinFilter; + /* 0x33 */ u8 mMagFilter; + /* 0x34 */ u16 mMinLOD; + /* 0x36 */ u16 mMaxLOD; + /* 0x38 */ s16 mLODBias; + /* 0x3A */ u8 mTlutName; + /* 0x3B */ u8 mFlags; + /* 0x3C */ void *field_0x3c; +}; } // namespace EGG diff --git a/include/nw4r/lyt/lyt_texMap.h b/include/nw4r/lyt/lyt_texMap.h index 2b15fafd..f1f82da5 100644 --- a/include/nw4r/lyt/lyt_texMap.h +++ b/include/nw4r/lyt/lyt_texMap.h @@ -1,9 +1,11 @@ #ifndef NW4R_LYT_TEXMAP_H #define NW4R_LYT_TEXMAP_H #include "common.h" -#include "rvl/GX.h" // IWYU pragma: export #include "rvl/TPL/TPL.h" +#include "rvl/GX.h" // IWYU pragma: export + + namespace nw4r { namespace lyt { namespace detail { diff --git a/include/rvl/GX/GXTexture.h b/include/rvl/GX/GXTexture.h index 0b3c14dc..c35865a0 100644 --- a/include/rvl/GX/GXTexture.h +++ b/include/rvl/GX/GXTexture.h @@ -29,7 +29,7 @@ void GXInitTexObjLOD( u8 biasClampEnable, u8 edgeLODEnable, GXAnisotropy anisotropy ); void GXInitTexObjTlut(GXTexObj *, u32); -void GXInitTexObjCI(GXTexObj *, void *, u16, u16, GXTexFmt, GXTexWrapMode, GXTexWrapMode, u8, u32); +void GXInitTexObjCI(GXTexObj *, void *, u16, u16, GXCITexFmt, GXTexWrapMode, GXTexWrapMode, u8, u32); void GXInitTlutObj(GXTlutObj *, void *, GXTlutFmt, u16); void GXLoadTlut(GXTlutObj *, u32); diff --git a/src/egg/gfx/eggPalette.cpp b/src/egg/gfx/eggPalette.cpp index 425ecb04..bbe3205d 100644 --- a/src/egg/gfx/eggPalette.cpp +++ b/src/egg/gfx/eggPalette.cpp @@ -1,3 +1,23 @@ #include "egg/gfx/eggPalette.h" -namespace EGG {} // namespace EGG +namespace EGG { + +void Palette::storeTLUT(_GXTlut param_0, _GXTlutFmt param_1, JUTTransparency param_2, u16 param_3, void *param_4) { + mTlutName = param_0; + mFormat = param_1; + mTransparency = param_2; + mNumColors = param_3; + mColorTable = (ResTLUT *)param_4; + GXInitTlutObj(&mTlutObj, (void *)mColorTable, (GXTlutFmt)mFormat, mNumColors); +} + +bool Palette::load() { + bool check = mNumColors != 0; + if (check) { + GXLoadTlut(&mTlutObj, mTlutName); + } + + return check; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggTexture.cpp b/src/egg/gfx/eggTexture.cpp index 0e673cef..4d2e9a38 100644 --- a/src/egg/gfx/eggTexture.cpp +++ b/src/egg/gfx/eggTexture.cpp @@ -1,3 +1,119 @@ #include "egg/gfx/eggTexture.h" -namespace EGG {} // namespace EGG +namespace EGG { + +Texture::~Texture() { + if (getCaptureFlag()) { + delete[] field_0x3c; + } + if (getEmbPaletteDelFlag()) { + delete mEmbPalette; + } +} + +void Texture::storeTIMG(ResTIMG const *pTIMG, u8 param0) { + GXTlut tlut; + + if (pTIMG && param0 < GX_BIGTLUT0) { + mTexInfo = pTIMG; + mTexData = (void *)((int)mTexInfo + mTexInfo->imageOffset); + + if (mTexInfo->imageOffset == 0) { + mTexData = (void *)((int)mTexInfo + 0x20); + } + + mpPalette = NULL; + mTlutName = 0; + mWrapS = mTexInfo->wrapS; + mWrapT = mTexInfo->wrapT; + mMinFilter = mTexInfo->minFilter; + mMagFilter = mTexInfo->magFilter; + mMinLOD = mTexInfo->minLOD; + mMaxLOD = mTexInfo->maxLOD; + mLODBias = mTexInfo->LODBias; + + if (mTexInfo->numColors == 0) { + initTexObj(); + } else { + if (mTexInfo->numColors > 0x100) { + tlut = (GXTlut)((param0 % 4) + GX_BIGTLUT0); + } else { + tlut = (GXTlut)param0; + } + + if (mEmbPalette == NULL || !getEmbPaletteDelFlag()) { + mEmbPalette = new Palette( + tlut, (GXTlutFmt)mTexInfo->colorFormat, (JUTTransparency)mTexInfo->alphaEnabled, + mTexInfo->numColors, (void *)(&mTexInfo->format + mTexInfo->paletteOffset) + ); + mFlags = mFlags & 1 | 2; + } else { + mEmbPalette->storeTLUT( + tlut, (GXTlutFmt)mTexInfo->colorFormat, (JUTTransparency)mTexInfo->alphaEnabled, + mTexInfo->numColors, (void *)(&mTexInfo->format + mTexInfo->paletteOffset) + ); + } + attachPalette(mEmbPalette); + } + } +} + +void Texture::attachPalette(Palette *param_0) { + if (mTexInfo->indexTexture) { + if (param_0 == NULL && mEmbPalette != NULL) { + mpPalette = mEmbPalette; + } else { + mpPalette = param_0; + } + GXTlut name = (GXTlut)mpPalette->getTlutName(); + initTexObj(name); + } +} + +void Texture::initTexObj() { + GXBool mipmapEnabled; + if (mTexInfo->mipmapEnabled != 0) { + mipmapEnabled = 1; + } else { + mipmapEnabled = 0; + } + u8 *image = ((u8 *)mTexInfo); + image += (mTexInfo->imageOffset ? mTexInfo->imageOffset : 0x20); + GXInitTexObj( + &mTexObj, image, mTexInfo->width, mTexInfo->height, (GXTexFmt)mTexInfo->format, (GXTexWrapMode)mWrapS, + (GXTexWrapMode)mWrapT, mipmapEnabled + ); + GXInitTexObjLOD( + &mTexObj, (GXTexFilter)mMinFilter, (GXTexFilter)mMagFilter, mMinLOD / 8.0f, mMaxLOD / 8.0f, mLODBias / 100.0f, + mTexInfo->biasClamp, mTexInfo->doEdgeLOD, (GXAnisotropy)mTexInfo->maxAnisotropy + ); +} + +void Texture::initTexObj(GXTlut param_0) { + GXBool mipmapEnabled; + if (mTexInfo->mipmapEnabled != 0) { + mipmapEnabled = 1; + } else { + mipmapEnabled = 0; + } + mTlutName = param_0; + u8 *image = ((u8 *)mTexInfo); + image += (mTexInfo->imageOffset ? mTexInfo->imageOffset : 0x20); + GXInitTexObjCI( + &mTexObj, image, mTexInfo->width, mTexInfo->height, (GXCITexFmt)mTexInfo->format, (GXTexWrapMode)mWrapS, + (GXTexWrapMode)mWrapT, mipmapEnabled, param_0 + ); + GXInitTexObjLOD( + &mTexObj, (GXTexFilter)mMinFilter, (GXTexFilter)mMagFilter, mMinLOD / 8.0f, mMaxLOD / 8.0f, mLODBias / 100.0f, + mTexInfo->biasClamp, mTexInfo->doEdgeLOD, (GXAnisotropy)mTexInfo->maxAnisotropy + ); +} + +void Texture::load(GXTexMapID param_0) { + if (mpPalette) { + mpPalette->load(); + } + GXLoadTexObj(&mTexObj, param_0); +} + +} // namespace EGG diff --git a/src/nw4r/g3d/g3d_anmtexpat.cpp b/src/nw4r/g3d/g3d_anmtexpat.cpp index 1dd1287b..587d77b8 100644 --- a/src/nw4r/g3d/g3d_anmtexpat.cpp +++ b/src/nw4r/g3d/g3d_anmtexpat.cpp @@ -499,10 +499,7 @@ void ApplyTexPatAnmResult(ResTexObj texObj, ResTlutObj tlutObj, const TexPatAnmR if (tex.IsCIFmt()) { tex.GetTexObjCIParam(&pTexData, &width, &height, &cifmt, &minLod, &maxLod, &mipmap); - GXInitTexObjCI( - pGXObj, pTexData, width, height, static_cast(cifmt), wrapS, wrapT, mipmap, - static_cast(i) - ); + GXInitTexObjCI(pGXObj, pTexData, width, height, cifmt, wrapS, wrapT, mipmap, static_cast(i)); } else { tex.GetTexObjParam(&pTexData, &width, &height, &fmt, &minLod, &maxLod, &mipmap); diff --git a/src/nw4r/g3d/res/g3d_resmat.cpp b/src/nw4r/g3d/res/g3d_resmat.cpp index be7a96da..6aee3a52 100644 --- a/src/nw4r/g3d/res/g3d_resmat.cpp +++ b/src/nw4r/g3d/res/g3d_resmat.cpp @@ -1566,9 +1566,7 @@ void ResTexPlttInfo::BindTex_(const ResTex tex, ResTexObj texObj) { GXCITexFmt fmtCi; tex.GetTexObjCIParam(&pTexData, &width, &height, &fmtCi, &minLod, &maxLod, &mipmap); - GXInitTexObjCI( - pGXObj, pTexData, width, height, static_cast(fmtCi), r.wrap_s, r.wrap_t, mipmap, r.tlutID - ); + GXInitTexObjCI(pGXObj, pTexData, width, height, fmtCi, r.wrap_s, r.wrap_t, mipmap, r.tlutID); } else { GXTexFmt fmt; tex.GetTexObjParam(&pTexData, &width, &height, &fmt, &minLod, &maxLod, &mipmap); diff --git a/src/nw4r/lyt/lyt_texMap.cpp b/src/nw4r/lyt/lyt_texMap.cpp index 47288be1..a1bf8c3f 100644 --- a/src/nw4r/lyt/lyt_texMap.cpp +++ b/src/nw4r/lyt/lyt_texMap.cpp @@ -19,8 +19,8 @@ void TexMap::Get(GXTexObj *pTexObj) const { if (detail::IsCITexelFormat(GetTexelFormat())) { u32 tlutName = GXGetTexObjTlut(pTexObj); GXInitTexObjCI( - pTexObj, GetImage(), GetWidth(), GetHeight(), GetTexelFormat(), GetWrapModeS(), GetWrapModeT(), IsMipMap(), - tlutName + pTexObj, GetImage(), GetWidth(), GetHeight(), (GXCITexFmt)GetTexelFormat(), GetWrapModeS(), GetWrapModeT(), + IsMipMap(), tlutName ); } else { GXInitTexObj( From 510df58ea4d587d3aeff295b4d05708fffd52d00 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 22 Mar 2025 12:34:18 +0100 Subject: [PATCH 29/62] eggLightObject good enough --- config/SOUE01/symbols.txt | 6 +- include/egg/gfx/eggLightObject.h | 23 ++- include/egg/gfx/eggLightTexture.h | 5 +- src/egg/gfx/eggLightObject.cpp | 270 ++++++++++++++++++++++++++---- 4 files changed, 256 insertions(+), 48 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 9e8abbca..b54e015c 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26621,9 +26621,9 @@ InitGX__Q23EGG11LightObjectCFP11_GXLightObj = .text:0x804A9D40; // type:function CopyToG3D_World__Q23EGG11LightObjectCFRQ34nw4r3g3d8LightObj = .text:0x804A9F40; // type:function size:0x150 CopyToG3D_View__Q23EGG11LightObjectCFRQ34nw4r3g3d8LightObjRCQ34nw4r4math5MTX34 = .text:0x804AA090; // type:function size:0x144 CopyFromG3D__Q23EGG11LightObjectFRCQ34nw4r3g3d11ResAnmLightfPQ23EGG11LightObjectb = .text:0x804AA1E0; // type:function size:0xD8 -FUN_804aa2c0 = .text:0x804AA2C0; // type:function size:0x9C -FUN_804aa360 = .text:0x804AA360; // type:function size:0x168 -FUN_804aa4d0 = .text:0x804AA4D0; // type:function size:0xA8 +ApplyAnmResultInner__Q23EGG11LightObjectFRCQ34nw4r3g3d14LightAnmResult = .text:0x804AA2C0; // type:function size:0x9C +ApplyAnmResultA__Q23EGG11LightObjectFRCQ34nw4r3g3d14LightAnmResult = .text:0x804AA360; // type:function size:0x168 +ApplyAnmResultB__Q23EGG11LightObjectFRCQ34nw4r3g3d14LightAnmResult = .text:0x804AA4D0; // type:function size:0xA8 CalcDirDist__Q23EGG11LightObjectFv = .text:0x804AA580; // type:function size:0xD4 CalcAt__Q23EGG11LightObjectFv = .text:0x804AA660; // type:function size:0x44 SetPos__Q23EGG11LightObjectFRCQ34nw4r4math4VEC3 = .text:0x804AA6B0; // type:function size:0x1C diff --git a/include/egg/gfx/eggLightObject.h b/include/egg/gfx/eggLightObject.h index 84fbdcf3..d9ff2455 100644 --- a/include/egg/gfx/eggLightObject.h +++ b/include/egg/gfx/eggLightObject.h @@ -1,8 +1,9 @@ #ifndef EGG_LIGHT_OBJ_H #define EGG_LIGHT_OBJ_H -#include "egg/math/eggVector.h" +#include "egg/egg_types.h" #include "egg/prim/eggBinary.h" +#include "nw4r/g3d/res/g3d_resanmlight.h" #include "nw4r/math/math_types.h" #include "rvl/GX/GXLight.h" #include "rvl/GX/GXTypes.h" @@ -23,7 +24,17 @@ public: void Reset(); void Calc(); void CalcView(nw4r::math::MTX34 const &); + + void fn_804A9C30(const LightTexture *, nw4r::math::VEC3 *, GXColor *) const; + void InitGX(GXLightObj *obj) const; + void CopyToG3D_World(nw4r::g3d::LightObj &) const; + void CopyToG3D_View(nw4r::g3d::LightObj &, const nw4r::math::MTX34 &) const; + void CopyFromG3D(const nw4r::g3d::ResAnmLight &, f32, EGG::LightObject *, bool); + + void ApplyAnmResultInner(const nw4r::g3d::LightAnmResult &); + void ApplyAnmResultA(const nw4r::g3d::LightAnmResult &); + bool ApplyAnmResultB(const nw4r::g3d::LightAnmResult &); void CalcAt(); void SetPos(const nw4r::math::VEC3 &); @@ -66,12 +77,12 @@ private: /* 0x48 */ f32 field_0x48; /* 0x4C */ nw4r::math::VEC3 field_0x4C; /* 0x58 */ nw4r::math::VEC3 field_0x58; - /* 0x64 */ f32 field_0x64; - /* 0x68 */ u16 field_0x68; + /* 0x64 */ f32 mShininess; + /* 0x68 */ u16 mFlags; /* 0x6C */ nw4r::math::VEC3 field_0x6C; - /* 0x78 */ GXColor field_0x78; - /* 0x7C */ nw4r::math::VEC3 field_0x7C; - /* 0x88 */ nw4r::math::VEC3 field_0x88; + /* 0x78 */ GXColor mLightColor; + /* 0x7C */ nw4r::math::VEC3 mViewPos; + /* 0x88 */ nw4r::math::VEC3 mViewAt; /* 0x94 */ nw4r::math::VEC3 field_0x94; /* 0xA0 */ u16 field_0xA0; }; diff --git a/include/egg/gfx/eggLightTexture.h b/include/egg/gfx/eggLightTexture.h index c278e227..59bf0907 100644 --- a/include/egg/gfx/eggLightTexture.h +++ b/include/egg/gfx/eggLightTexture.h @@ -53,12 +53,13 @@ public: const char *getName() const { return mName1; } - -private: + f32 getFloat(u16 idx) const { return mpFloatData[idx]; } +private: + u8 getByte1(u16 idx) const { return mpByteData1[idx]; } diff --git a/src/egg/gfx/eggLightObject.cpp b/src/egg/gfx/eggLightObject.cpp index 9eb4db95..1c5703c7 100644 --- a/src/egg/gfx/eggLightObject.cpp +++ b/src/egg/gfx/eggLightObject.cpp @@ -1,6 +1,10 @@ #include "egg/gfx/eggLightObject.h" +#include "common.h" #include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggLightTexture.h" +#include "nw4r/g3d/g3d_light.h" +#include "nw4r/g3d/res/g3d_resanmlight.h" #include "nw4r/math/math_arithmetic.h" #include "nw4r/math/math_types.h" #include "rvl/GX/GXLight.h" @@ -8,6 +12,12 @@ #include "rvl/MTX/mtxvec.h" #include "rvl/MTX/vec.h" +// TODO: This whole file does weird things with vectors! +// NSMBW symbol names indicate that functions use nw4r::math::VEC3 +// arguments and we have some nw4r PS inlines, but +// a fair number of vector assignments happen in a weird order +// which might indicate EGG::Vector3f? + namespace EGG { template <> @@ -35,17 +45,17 @@ LightObject::LightObject() mBlack(DrawGX::BLACK), field_0x3C(0), field_0x3D(1), - mSpotFn(0), - mDistAttnFn(0), + mSpotFn(GX_SP_OFF), + mDistAttnFn(GX_DA_OFF), field_0x40(90.0f), field_0x44(0.5f), field_0x48(0.5f), - field_0x64(16.0f), - field_0x68(0x661) {} + mShininess(16.0f), + mFlags(0x661) {} void LightObject::Reset() { SetPosAt(nw4r::math::VEC3(-10000.0f, 10000.0f, 10000.0f), zeroVec); - field_0x68 = 0x661; + mFlags = 0x661; mWhite = DrawGX::WHITE; mBlack = DrawGX::BLACK; field_0x30 = 1.0; @@ -54,24 +64,24 @@ void LightObject::Reset() { field_0x40 = 90.0; field_0x44 = 0.5; field_0x48 = 0.5; - mSpotFn = 0; - mDistAttnFn = 0; - field_0x64 = 16.0; + mSpotFn = GX_SP_OFF; + mDistAttnFn = GX_DA_OFF; + mShininess = 16.0; field_0x58.x = 1.0; field_0x4C.x = 1.0; field_0x58.z = 0.0; - field_0x4C.y = 0.0; - field_0x58.y = 0.0; field_0x4C.z = 0.0; + field_0x58.y = 0.0; + field_0x4C.y = 0.0; } void LightObject::Calc() { field_0x6C = mDir; - field_0x78 = mWhite; + mLightColor = mWhite; } void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) { - if ((field_0x68 & 1) == 0) { + if ((mFlags & 1) == 0) { return; } @@ -80,35 +90,35 @@ void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) { case 3: { // Halp f32 scale = -1.0f; - field_0x88.x = 0.0f; + mViewAt.x = 0.0f; field_0x94.x = 0.0f; - field_0x88.y = 0.0f; + mViewAt.y = 0.0f; field_0x94.y = 0.0f; field_0x94.z = -1.0f; - field_0x88.z = scale * mDist; - field_0x7C.z = 0.0f; - field_0x7C.y = 0.0f; - field_0x7C.x = 0.0f; + mViewAt.z = scale * mDist; + mViewPos.z = 0.0f; + mViewPos.y = 0.0f; + mViewPos.x = 0.0f; break; } case 4: { // Halp f32 scale = 1.0f; - field_0x7C.x = 0.0f; + mViewPos.x = 0.0f; field_0x94.x = 0.0f; - field_0x7C.y = 0.0f; + mViewPos.y = 0.0f; field_0x94.y = 0.0f; field_0x94.z = 1.0f; - field_0x7C.z = scale * mDist; - field_0x88.z = 0.0f; - field_0x88.y = 0.0f; - field_0x88.x = 0.0f; + mViewPos.z = scale * mDist; + mViewAt.z = 0.0f; + mViewAt.y = 0.0f; + mViewAt.x = 0.0f; break; } case 2: field_0x94 = mDir; - field_0x88 = mAt; - field_0x7C = mPos; + mViewAt = mAt; + mViewPos = mPos; break; } @@ -126,15 +136,30 @@ void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) { field_0x6C.z = 1.0f; } } - PSMTXMultVec(viewMtx, mPos, field_0x7C); - PSMTXMultVec(viewMtx, mAt, field_0x88); + PSMTXMultVec(viewMtx, mPos, mViewPos); + PSMTXMultVec(viewMtx, mAt, mViewAt); nw4r::math::VEC3TransformNormal(&field_0x94, &viewMtx, &field_0x6C); } } +void LightObject::fn_804A9C30(const LightTexture *tex, nw4r::math::VEC3 *pVec, GXColor *color) const { + *pVec = field_0x94; + *color = mLightColor; + f32 f = tex->getFloat(mIndex); + if (f < 1.0f) { + color->r = color->r * f; + color->g = color->g * f; + color->b = color->b * f; + color->a = color->a * f; + } else { + // Yes + *color = *color; + } +} + void LightObject::InitGX(GXLightObj *obj) const { - if ((field_0x68 & 1) != 0 && ((field_0x68 >> 6) & 1) != 0) { - GXInitLightColor(obj, field_0x78); + if ((mFlags & 1) != 0 && ((mFlags >> 6) & 1) != 0) { + GXInitLightColor(obj, mLightColor); switch (field_0x3D) { case 1: { nw4r::math::VEC3 tmp = field_0x94 * -1e10f; @@ -143,31 +168,31 @@ void LightObject::InitGX(GXLightObj *obj) const { break; } case 0: { - GXInitLightPos(obj, field_0x7C.x, field_0x7C.y, field_0x7C.z); + GXInitLightPos(obj, mViewPos.x, mViewPos.y, mViewPos.z); GXInitLightDir(obj, zeroVec[0], zeroVec[1], zeroVec[2]); break; } case 2: { - GXInitLightPos(obj, field_0x7C.x, field_0x7C.y, field_0x7C.z); + GXInitLightPos(obj, mViewPos.x, mViewPos.y, mViewPos.z); GXInitLightDir(obj, field_0x94.x, field_0x94.y, field_0x94.z); break; } } - if ((field_0x68 & 0x80) != 0) { + if ((mFlags & 0x80) != 0) { GXInitLightAttnA(obj, field_0x4C.x, field_0x4C.y, field_0x4C.z); } else { GXInitLightSpot(obj, field_0x40 > 0.0f ? field_0x40 : 0.0001f, getSpotFn()); } - if ((field_0x68 & 0x100) != 0) { + if ((mFlags & 0x100) != 0) { GXInitLightAttnK(obj, field_0x58.x, field_0x58.y, field_0x58.z); } else { GXInitLightDistAttn(obj, field_0x44 * getDistance(), field_0x48, getDistAttnFn()); } - if ((field_0x68 & 0x800) != 0) { - f32 ka = field_0x64 / 2.0f; + if ((mFlags & 0x800) != 0) { + f32 ka = mShininess / 2.0f; GXInitLightAttn(obj, 0.0f, 0.0f, 1.0f, ka, 0.0f, 1.0f - ka); } @@ -176,6 +201,178 @@ void LightObject::InitGX(GXLightObj *obj) const { } } +void LightObject::CopyToG3D_World(nw4r::g3d::LightObj &g3dObj) const { + if ((mFlags & 1) != 0 && (mFlags & 0x40) != 0) { + g3dObj.Clear(); + if ((mFlags & 0x200) == 0) { + g3dObj.DisableColor(); + } + if ((mFlags & 0x400) == 0) { + g3dObj.DisableAlpha(); + } + + g3dObj.Enable(); + g3dObj.InitLightColor(mLightColor); + + if ((mFlags & 0x80) != 0) { + g3dObj.InitLightAttnA(field_0x4C.x, field_0x4C.y, field_0x4C.z); + } else { + g3dObj.InitLightSpot(field_0x40 > 0.0f ? field_0x40 : 0.0001f, getSpotFn()); + } + + if ((mFlags & 0x100) != 0) { + g3dObj.InitLightAttnK(field_0x58.x, field_0x58.y, field_0x58.z); + } else { + g3dObj.InitLightDistAttn(field_0x44 * getDistance(), field_0x48, getDistAttnFn()); + } + + if ((mFlags & 0x800) != 0) { + g3dObj.InitLightShininess(mShininess); + } + } else { + g3dObj.Disable(); + } +} + +void LightObject::CopyToG3D_View(nw4r::g3d::LightObj &g3dObj, const nw4r::math::MTX34 &viewMtx) const { + if (!g3dObj.IsEnable()) { + return; + } + + // TODO + if (!(mFlags & 0x800)) { + nw4r::math::VEC3 dir; + nw4r::math::VEC3 pos; + switch (field_0x3D) { + case 1: { + nw4r::math::VEC3TransformNormal(&dir, &viewMtx, &field_0x94); + nw4r::math::VEC3Scale(&pos, &dir, -1e10f); + dir.z = 0.0f; + dir.y = 0.0f; + dir.x = 0.0f; + break; + } + case 0: { + PSMTXMultVec(viewMtx, mViewPos, pos); + dir.z = 0.0f; + dir.y = 0.0f; + dir.x = 0.0f; + break; + } + case 2: { + PSMTXMultVec(viewMtx, mViewPos, pos); + nw4r::math::VEC3TransformNormal(&dir, &viewMtx, &field_0x94); + break; + } + } + g3dObj.InitLightPos(pos.x, pos.y, pos.z); + g3dObj.InitLightDir(dir.x, dir.y, dir.z); + } else { + g3dObj.InitSpecularDir(mDir.x, mDir.y, mDir.z); + } +} + +void LightObject::CopyFromG3D( + const nw4r::g3d::ResAnmLight &g3dLight, f32 frame, EGG::LightObject *optObj, bool skipDoingSomething +) { + nw4r::g3d::LightAnmResult result; + g3dLight.GetAnmResult(&result, frame); + if (!skipDoingSomething || (result.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_ENABLE) != 0) { + if ((result.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_ENABLE) != 0) { + ApplyAnmResultA(result); + if (optObj != nullptr && optObj->ApplyAnmResultB(result)) { + optObj->field_0x06 = mIndex; + optObj->mFlags |= 2; + } + } else { + // TODO + mFlags = mFlags & 0xFFFE; + if (optObj != nullptr) { + optObj->mFlags = optObj->mFlags & 0xFFFE; + } + } + } +} + +void LightObject::ApplyAnmResultInner(const nw4r::g3d::LightAnmResult &res) { + // TODO + mFlags = mFlags & 0xF07E; + field_0x40 = 90.0f; + field_0x44 = 0.5f; + field_0x48 = 0.5f; + mSpotFn = GX_SP_OFF; + mDistAttnFn = GX_DA_OFF; + mShininess = 16.0f; + // ... + field_0x58.x = 1.0f; + field_0x4C.x = 1.0f; + field_0x58.z = 0.0f; + field_0x4C.z = 0.0f; + field_0x58.y = 0.0f; + field_0x4C.y = 0.0f; + if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_COLOR_ENABLE) != 0) { + mFlags |= 0x200; + } + if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_ALPHA_ENABLE) != 0) { + mFlags |= 0x400; + } + if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_ENABLE) != 0) { + mFlags |= 1; + } +} + +void LightObject::ApplyAnmResultA(const nw4r::g3d::LightAnmResult &res) { + ApplyAnmResultInner(res); + switch ((int)(res.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_TYPE_MASK)) { + case 0: { + field_0x3D = 0; + mWhite = res.color; + SetPosAt(res.pos, res.pos); + field_0x40 = 0.0f; + mSpotFn = GX_SP_OFF; + field_0x44 = res.refDistance; + field_0x48 = res.refBrightness; + mDistAttnFn = res.distFunc; + break; + } + case 1: { + field_0x3D = 1; + mWhite = res.color; + SetPosAt(res.pos, res.aim); + mSpotFn = GX_SP_OFF; + mDistAttnFn = GX_AF_SPEC; + break; + } + case 2: { + field_0x3D = 2; + mWhite = res.color; + SetPosAt(res.pos, res.aim); + mSpotFn = res.spotFunc; + field_0x40 = res.cutoff; + mDistAttnFn = res.distFunc; + field_0x44 = res.refDistance; + field_0x48 = res.refBrightness; + break; + } + } +} + +bool LightObject::ApplyAnmResultB(const nw4r::g3d::LightAnmResult &res) { + if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_SPECULAR_ENABLE) != 0) { + ApplyAnmResultInner(res); + field_0x3D = 1; + mWhite = res.specColor; + SetPosAt(res.pos, res.aim); + mFlags |= 0x800; + mShininess = res.shininess; + return true; + } else { + // TODO + mFlags = mFlags & 0xFFFE; + return false; + } +} + void LightObject::CalcDirDist() { mDir.x = mAt.x - mPos.x; mDir.y = mAt.y - mPos.y; @@ -217,7 +414,6 @@ void LightObject::SetPosAt(nw4r::math::VEC3 const &pos, nw4r::math::VEC3 const & CalcDirDist(); } - void LightObject::SetBinaryInner(const Bin &bin) {} void LightObject::GetBinaryInner(Bin *bin) const {} From b16089a834bbdb3a68e64d1b54824d7768be63d5 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sat, 22 Mar 2025 13:50:29 -0400 Subject: [PATCH 30/62] convert CpuTexture to use ResTIMG header --- include/egg/gfx/eggCpuTexture.h | 34 +---- include/egg/gfx/eggTexture.h | 1 - src/egg/gfx/eggCpuTexture.cpp | 214 +++++++++++++++++--------------- 3 files changed, 118 insertions(+), 131 deletions(-) diff --git a/include/egg/gfx/eggCpuTexture.h b/include/egg/gfx/eggCpuTexture.h index 5c2e55cb..11096550 100644 --- a/include/egg/gfx/eggCpuTexture.h +++ b/include/egg/gfx/eggCpuTexture.h @@ -3,38 +3,14 @@ #include "common.h" #include "egg/core/eggHeap.h" +#include "egg/gfx/eggTexture.h" #include "rvl/GX/GXTexture.h" #include "rvl/GX/GXTypes.h" namespace EGG { class CpuTexture { - public: - struct Header { - u8 mTexFormat; - u8 BYTE_0x1; - u16 mWidth; - u16 mHeight; - u8 mWrapS; - u8 mWrapT; - u8 BYTE_0x8; - u8 BYTE_0x9; - u16 SHORT_0xA; - u32 WORD_0xC; - u8 BYTE_0xD; - u8 BYTE_0xE; - u8 BYTE_0xF; - u8 BYTE_0x10; - u8 mMinFilt; - u8 mMagFilt; - u8 BYTE_0x13; - u8 BYTE_0x14; - u8 BYTE_0x15; - u16 SHORT_0x16; - u32 WORD_0x18; - }; - enum TexFlag { CONFIGURED = 0x1, HAS_HEADER = 0x2, @@ -60,10 +36,10 @@ public: u32 getTexBufferSize() const; void buildHeader() const; - Header *initHeader(); + ResTIMG *initHeader(); void fillNormalMapSphere(f32, f32); - void fillGradient(int op, int, u16, u16, const GXColor&, const GXColor&, bool, bool); + void fillGradient(int op, int, u16, u16, const GXColor &, const GXColor &, bool, bool); void setColor(u16 x, u16 y, GXColor color); GXColor getColor(u16 x, u16 y) const; @@ -127,8 +103,8 @@ public: mMagFilt = filt; } - Header *getHeader() const { - return (Header *)((u8 *)dataPtr - sizeof(Header)); + ResTIMG *getHeader() const { + return (ResTIMG *)((u8 *)dataPtr - sizeof(ResTIMG)); } void *getBuffer() const { diff --git a/include/egg/gfx/eggTexture.h b/include/egg/gfx/eggTexture.h index e166b882..10420822 100644 --- a/include/egg/gfx/eggTexture.h +++ b/include/egg/gfx/eggTexture.h @@ -29,7 +29,6 @@ struct ResTIMG { /* 0x16 */ s8 minLOD; /* 0x17 */ s8 maxLOD; /* 0x18 */ u8 mipmapCount; - /* 0x19 */ u8 unknown; /* 0x1A */ s16 LODBias; /* 0x1C */ u32 imageOffset; }; diff --git a/src/egg/gfx/eggCpuTexture.cpp b/src/egg/gfx/eggCpuTexture.cpp index fc927b2f..f5b925c9 100644 --- a/src/egg/gfx/eggCpuTexture.cpp +++ b/src/egg/gfx/eggCpuTexture.cpp @@ -3,6 +3,7 @@ #include "common.h" #include "egg/core/eggHeap.h" #include "egg/gfx/eggGXUtility.h" +#include "egg/gfx/eggTexture.h" #include "egg/math/eggVector.h" #include "rvl/GX/GXTexture.h" #include "rvl/GX/GXTypes.h" @@ -105,7 +106,7 @@ CpuTexture::CpuTexture(const GXTexObj *pObj) { mWrapT = GXGetTexObjWrapT(pObj); mMinFilt = GXGetTexObjMinFilt(pObj); mMagFilt = GXGetTexObjMagFilt(pObj); - // why? + // Convert Physical to Virtual Address dataPtr = (char *)GXGetTexObjData(pObj) - 0x80000000; mpBuffer = nullptr; } @@ -139,51 +140,131 @@ void CpuTexture::getTexObj(GXTexObj *pObj) const { } void CpuTexture::flush() const { - u32 size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + size_t size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); DCFlushRange(dataPtr, size); } void CpuTexture::buildHeader() const { - Header *pHdr = getHeader(); + ResTIMG *pHdr = getHeader(); - pHdr->mTexFormat = mTexFormat; - pHdr->BYTE_0x1 = 1; - pHdr->mWidth = mWidth; - pHdr->mHeight = mHeight; - pHdr->mWrapS = mWrapS; - pHdr->mWrapT = mWrapT; - pHdr->BYTE_0x8 = 0; - pHdr->BYTE_0x9 = 0; - pHdr->SHORT_0xA = 0; - pHdr->WORD_0xC = 0; - pHdr->BYTE_0xD = 0; - pHdr->BYTE_0xE = 0; - pHdr->BYTE_0xF = 0; - pHdr->BYTE_0x10 = 0; - pHdr->mMinFilt = mMinFilt; - pHdr->mMagFilt = mMagFilt; - pHdr->BYTE_0x13 = 0; - pHdr->BYTE_0x14 = 0; - pHdr->BYTE_0x15 = 1; - pHdr->SHORT_0x16 = 0; - pHdr->WORD_0x18 = 32; + pHdr->format = mTexFormat; + pHdr->alphaEnabled = 1; + pHdr->width = mWidth; + pHdr->height = mHeight; + pHdr->wrapS = mWrapS; + pHdr->wrapT = mWrapT; + pHdr->indexTexture = 0; + pHdr->colorFormat = 0; + pHdr->numColors = 0; + pHdr->paletteOffset = 0; + pHdr->mipmapEnabled = 0; + pHdr->doEdgeLOD = 0; + pHdr->biasClamp = 0; + pHdr->maxAnisotropy = 0; + pHdr->minFilter = mMinFilt; + pHdr->magFilter = mMagFilt; + pHdr->minLOD = 0; + pHdr->maxLOD = 0; + pHdr->mipmapCount = 1; + pHdr->LODBias = 0; + pHdr->imageOffset = sizeof(ResTIMG); +} + +extern "C" double sqrt(double); + +void CpuTexture::fillNormalMapSphere(f32 f1, f32 f2) { + // NONMATCHING + // fpr regswaps + f32 mid = static_cast(mWidth / 2); + + for (u16 y = 0; y < mHeight; y++) { + for (u16 x = 0; x < mWidth; x++) { + Vector3f vec; + GXColor c; + + f32 fx = f1 * ((x + f2) - mid); + f32 fy = f1 * -((y + f2) - mid); + f32 fz = mid * mid - (fx * fx + fy * fy); + + vec.x = fx; + vec.y = fy; + vec.z = fz < 0.0f ? 0.0f : (f32)sqrt(fz); + + PSVECNormalize(vec, vec); + GXUtility::getNormalColor(c, vec); + c.r = c.a; + setColor(x, y, c); + } + } + flush(); +} + +void CpuTexture::fillGradient( + int op, int unk, u16 start, u16 end, const GXColor &c1, const GXColor &c2, bool b1, bool b2 +) { + GXColor gradient[1024]; + GXColor colors[256]; + + // NONMATCHING - regswaps + bool swapMode = unk == 0x73 || unk == 0x53; + + u16 width = swapMode ? mWidth : mHeight; + int size = width; + u16 height = swapMode ? mHeight : mWidth; + int mid = width / 2; + makeGradient(op, gradient, size, start, end, c1, c2); + if (b1) { + for (int i2 = mid, i = 0; i < size; i2++, i++) { + colors[i].r = gradient[i < mid ? i2 : i - mid].r; + colors[i].g = gradient[i < mid ? i2 : i - mid].g; + colors[i].b = gradient[i < mid ? i2 : i - mid].b; + colors[i].a = gradient[i < mid ? i2 : i - mid].a; + } + + for (int i = 0; i < size; i++) { + gradient[i] = colors[i]; + } + } + + u16 start2 = b2 ? 0 : start; + u16 end2 = b2 ? size : end; + + for (u16 x = start2; x < end2; x++) { + for (u16 y = 0; y < height; y++) { + if (swapMode) { + setColor(x, y, gradient[x]); + } else { + setColor(y, x, gradient[x]); + } + } + } + flush(); } void CpuTexture::alloc(Heap *pHeap) { - Heap *heap = pHeap == nullptr ? Heap::getCurrentHeap() : pHeap; - u32 size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + Heap *heap = !pHeap ? Heap::getCurrentHeap() : pHeap; + + size_t size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + mpBuffer = new (heap, 0x20) char[size]; setBuffer(mpBuffer); + mFlags |= NEEDS_BUFFER_FREE; } void CpuTexture::allocWithHeaderDebug(Heap *pHeap) { - Heap *heap = pHeap == nullptr ? Heap::getCurrentHeap() : pHeap; - u32 size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); - mpBuffer = new (heap, 0x20) char[size + 0x20]; - char *actualBuf = mpBuffer + 0x20; - setBuffer(mpBuffer + 0x20); - if (actualBuf != nullptr) { + Heap *heap = !pHeap ? Heap::getCurrentHeap() : pHeap; + + size_t size = GXGetTexBufferSize(mWidth, mHeight, getFormat(), false, true); + + // Textures need 32-bit alignment ( ptr is represented with ptr >> 5 ) + mpBuffer = new (heap, 0x20) char[size + sizeof(ResTIMG)]; + + // Texture has Header -> offset to actual image data + void *imageData = mpBuffer + sizeof(ResTIMG); + + setBuffer(imageData); + if (imageData != nullptr) { mFlags |= HAS_HEADER; } mFlags |= NEEDS_BUFFER_FREE; @@ -193,7 +274,6 @@ void CpuTexture::allocWithHeaderDebug(Heap *pHeap) { void CpuTexture::allocate(Heap *pHeap) { alloc(pHeap); } - void CpuTexture::setColor(u16 x, u16 y, GXColor color) { // NONMATCHING switch (getFormat()) { @@ -268,72 +348,4 @@ GXColor CpuTexture::getColor(u16 x, u16 y) const { } return c; } - -extern "C" double sqrt(double); - -void CpuTexture::fillNormalMapSphere(f32 f1, f32 f2) { - // NONMATCHING - // fpr regswaps - f32 mid = static_cast(mWidth / 2); - for (u16 y = 0; y < mHeight; y++) { - for (u16 x = 0; x < mWidth; x++) { - Vector3f vec; - vec.x = f1 * ((x + f2) - mid); - vec.y = f1 * -((y + f2) - mid); - f32 z = mid * mid - (vec.x * vec.x + vec.y * vec.y); - vec.z = z < 0.0f ? 0.0f : (f32)sqrt(z); - PSVECNormalize(vec, vec); - GXColor c; - GXUtility::getNormalColor(c, vec); - c.r = c.a; - setColor(x, y, c); - } - } - flush(); -} - -void CpuTexture::fillGradient( - int op, int unk, u16 start, u16 end, const GXColor &c1, const GXColor &c2, bool b1, bool b2 -) { - GXColor gradient[1024]; - GXColor colors[256]; - - - // NONMATCHING - regswaps - bool swapMode = unk == 0x73 || unk == 0x53; - - u16 width = swapMode ? mWidth : mHeight; - int size = width; - u16 height = swapMode ? mHeight : mWidth; - int mid = width / 2; - makeGradient(op, gradient, size, start, end, c1, c2); - if (b1) { - int i2 = mid; - for (int i = 0; i < size; i++, i2++) { - colors[i].r = gradient[i < mid ? i2 : i - mid].r; - colors[i].g = gradient[i < mid ? i2 : i - mid].g; - colors[i].b = gradient[i < mid ? i2 : i - mid].b; - colors[i].a = gradient[i < mid ? i2 : i - mid].a; - } - - for (int i = 0; i < size; i++) { - gradient[i] = colors[i]; - } - } - - u16 start2 = b2 ? 0 : start; - u16 end2 = b2 ? size : end; - - for (u16 x = start2; x < end2; x++) { - for (u16 y = 0; y < height; y++) { - if (swapMode) { - setColor(x, y, gradient[x & 0xFFFF]); - } else { - setColor(y, x, gradient[x & 0xFFFF]); - } - } - } - flush(); -} - } // namespace EGG From b3732b0c456b6fba6843d6a08a6ec74911b05e62 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 22 Mar 2025 23:46:44 +0100 Subject: [PATCH 31/62] LightManager start --- config/SOUE01/splits.txt | 3 ++ config/SOUE01/symbols.txt | 2 +- include/egg/gfx/eggLight.h | 38 ---------------- include/egg/gfx/eggLightManager.h | 73 ++++++++++++++++++++++++++++++ include/egg/gfx/eggLightObject.h | 12 +++++ include/m/m3d/m3d.h | 4 +- src/egg/gfx/eggLightManager.cpp | 75 ++++++++++++++++++++++++++++++- src/egg/gfx/eggLightObject.cpp | 7 ++- src/m/m3d/m3d.cpp | 3 ++ 9 files changed, 169 insertions(+), 48 deletions(-) delete mode 100644 include/egg/gfx/eggLight.h create mode 100644 include/egg/gfx/eggLightManager.h diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 65ba25c3..301d92d7 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2254,6 +2254,9 @@ egg/gfx/eggIScnProc.cpp: egg/gfx/eggLightManager.cpp: .text start:0x804A7F80 end:0x804A9808 + .data start:0x8056F068 end:0x8056F098 + .sdata start:0x80574F28 end:0x80574F30 + .sdata2 start:0x8057F678 end:0x8057F690 egg/gfx/eggLightObject.cpp: .text start:0x804A9810 end:0x804AB24C diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index b54e015c..7f74cee0 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -37369,7 +37369,7 @@ __vt__Q23EGG10FogManager = .data:0x8056F010; // type:object size:0x1C __vt__Q23EGG7Frustum = .data:0x8056F030; // type:object size:0x14 EGG__GfxEnginer__Configuration__vtable = .data:0x8056F048; // type:object size:0x10 __vt__Q23EGG8IScnProc = .data:0x8056F058; // type:object size:0x10 -EGG__LightManager__vtable = .data:0x8056F068; // type:object size:0x30 +__vt__Q23EGG12LightManager = .data:0x8056F068; // type:object size:0x2C __vt__Q23EGG11LightObject = .data:0x8056F098; // type:object size:0x20 __vt__Q23EGG12LightTexture = .data:0x8056F0B8; // type:object size:0x38 __vt__Q23EGG19LightTextureManager = .data:0x8056F0F0; // type:object size:0x1C diff --git a/include/egg/gfx/eggLight.h b/include/egg/gfx/eggLight.h deleted file mode 100644 index 67692962..00000000 --- a/include/egg/gfx/eggLight.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef EGG_LIGHT_H -#define EGG_LIGHT_H - -#include "egg/prim/eggBinary.h" -#include "nw4r/types_nw4r.h" - -namespace EGG { - -class LightTextureManager; - -// TODO: Fill out more -class LightManager : public IBinary { -public: - struct BinData {}; - // vt at 0x00 - LightManager(u32, u32, u8); - virtual ~LightManager(); - virtual void SetBinaryInner(const Bin &) override; - virtual void GetBinaryInner(Bin *) const override; - virtual size_t GetBinarySize() const override; - virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; - virtual void Reset(); - virtual void Calc(nw4r::g3d::ScnRoot *); - virtual void CalcView(const nw4r::math::MTX34 &, u8, nw4r::g3d::ScnRoot *); - virtual void DoneDraw(); - - LightTextureManager *GetTextureMgr() const { - return mTextureMgr; - } - - u8 TODO_0x04[0x14 - 0x04]; - LightTextureManager *mTextureMgr; - u8 TODO_0x18[0x28 - 0x18]; -}; - -} // namespace EGG - -#endif diff --git a/include/egg/gfx/eggLightManager.h b/include/egg/gfx/eggLightManager.h new file mode 100644 index 00000000..d1ed1cb8 --- /dev/null +++ b/include/egg/gfx/eggLightManager.h @@ -0,0 +1,73 @@ +#ifndef EGG_LIGHT_MANAGER_H +#define EGG_LIGHT_MANAGER_H + +#include "egg/egg_types.h" +#include "egg/gfx/eggLightObject.h" +#include "egg/prim/eggBinary.h" +#include "nw4r/types_nw4r.h" +#include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +// TODO: Fill out more +class LightManager : public IBinary { + struct LightData { + /* 0x00 */ LightObject mLightObject; + }; + + // ??? + union Counts { + struct { + /* 0x00 */ u8 mNumEggLightObjects; + /* 0x01 */ u8 mNumUnks; + }; + }; + + struct Unk1 { + /* 0x00 */ GXColor mColor; + /* 0x04 */ const char *mStr; + /* 0x08 */ u8 field_0x08; + }; + +public: + struct BinData {}; + // vt at 0x00 + LightManager(u32, u32, u8); + virtual ~LightManager(); + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual size_t GetBinarySize() const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + virtual void Reset(); + virtual void Calc(nw4r::g3d::ScnRoot *); + virtual void CalcView(const nw4r::math::MTX34 &, u8, nw4r::g3d::ScnRoot *); + virtual void DoneDraw(); + + void BecomeInvalidLight(int); + + LightTextureManager *GetTextureMgr() const { + return mpTextureMgr; + } + + LightObject *GetLightObject(int i) { + return &mpLightData[i].mLightObject; + } + + /* 0x04 */ Counts mCounts0x04; + /* 0x06 */ Counts mCounts0x06; + /* 0x08 */ LightData *mpLightData; + /* 0x0C */ Unk1 *mpUnk1; + /* 0x10 */ GXLightObj *mpLightObjs; + /* 0x14 */ LightTextureManager *mpTextureMgr; + /* 0x18 */ GXColor mColor; + /* 0x1C */ u8 field_0x1C; + /* 0x1D */ u8 field_0x1D; + /* 0x1E */ u16 mFlags; + /* 0x20 */ u32 field_0x20; + /* 0x24 */ s16 field_0x24; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggLightObject.h b/include/egg/gfx/eggLightObject.h index d9ff2455..ac7f8ceb 100644 --- a/include/egg/gfx/eggLightObject.h +++ b/include/egg/gfx/eggLightObject.h @@ -58,6 +58,18 @@ public: return mDist; } + void SetIndex(u16 index) { + mIndex = index; + } + + void ClearField0xA0() { + field_0xA0 = 0; + } + + void ClearFlag4() { + mFlags = mFlags & 0xFFFE; + } + private: /* 0x04 */ u16 mIndex; /* 0x06 */ u16 field_0x06; diff --git a/include/m/m3d/m3d.h b/include/m/m3d/m3d.h index e1503ecf..db977ea8 100644 --- a/include/m/m3d/m3d.h +++ b/include/m/m3d/m3d.h @@ -1,9 +1,7 @@ #ifndef M3D_H #define M3D_H -#include "egg/core/eggHeap.h" -#include "egg/gfx/eggFogManager.h" -#include "egg/gfx/eggLight.h" +#include "egg/egg_types.h" #include "m/m_allocator.h" #include "nw4r/g3d/g3d_scnroot.h" diff --git a/src/egg/gfx/eggLightManager.cpp b/src/egg/gfx/eggLightManager.cpp index c842a6ec..ba8666b5 100644 --- a/src/egg/gfx/eggLightManager.cpp +++ b/src/egg/gfx/eggLightManager.cpp @@ -1,3 +1,74 @@ -#include "egg/gfx/eggLight.h" +#include "egg/gfx/eggLightManager.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/egg_types.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggLightObject.h" +#include "egg/gfx/eggLightTextureMgr.h" +#include "rvl/GX/GXLight.h" + +namespace EGG { + +LightManager::LightManager(u32 p1, u32 p2, u8 p3) { + Counts c; + c.mNumEggLightObjects = p1; + c.mNumUnks = p2; + + mCounts0x04 = c; + mCounts0x06 = c; + mpLightData = nullptr; + mpUnk1 = nullptr; + mpTextureMgr = nullptr; + + field_0x1C = p3; + mFlags = 0x40; + field_0x20 = 0; + field_0x24 = -1; + + mpTextureMgr = new LightTextureManager(this); + u16 numGxObjs = mCounts0x04.mNumEggLightObjects < 8 ? mCounts0x04.mNumEggLightObjects : 8; + mpLightObjs = new GXLightObj[field_0x1C * numGxObjs](); + mpLightData = new LightData[mCounts0x04.mNumEggLightObjects](); + mpUnk1 = new Unk1[mCounts0x04.mNumUnks](); + + for (int i = 0; i < mCounts0x04.mNumEggLightObjects; i++) { + GetLightObject(i)->SetIndex(i); + GetLightObject(i)->ClearField0xA0(); + BecomeInvalidLight(i); + } + + for (u16 i = 0; i < (u32)mCounts0x04.mNumUnks; i++) { + mpUnk1[i].field_0x08 = 0; + } + + Reset(); +} + +LightManager::~LightManager() { + delete mpTextureMgr; + delete[] mpLightObjs; + delete[] mpLightData; + delete[] mpUnk1; +} + +static const char *resetPattern = "--"; + +void LightManager::Reset() { + for (int i = 0; i < mCounts0x04.mNumEggLightObjects; i++) { + LightObject *obj = GetLightObject(i); + obj->Reset(); + if (i > 0) { + obj->ClearFlag4(); + } + } + + for (u16 i = 0; i < (u32)mCounts0x04.mNumUnks; i++) { + mpUnk1[i].mColor = (GXColor){0x64, 0x64, 0x64, 0xFF}; + mpUnk1[i].mStr = resetPattern; + } + mColor = DrawGX::BLACK; + field_0x1D = 0; + mFlags = mFlags & 0xFFE0; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggLightObject.cpp b/src/egg/gfx/eggLightObject.cpp index 1c5703c7..f24a2159 100644 --- a/src/egg/gfx/eggLightObject.cpp +++ b/src/egg/gfx/eggLightObject.cpp @@ -286,9 +286,9 @@ void LightObject::CopyFromG3D( } } else { // TODO - mFlags = mFlags & 0xFFFE; + ClearFlag4(); if (optObj != nullptr) { - optObj->mFlags = optObj->mFlags & 0xFFFE; + optObj->ClearFlag4(); } } } @@ -367,8 +367,7 @@ bool LightObject::ApplyAnmResultB(const nw4r::g3d::LightAnmResult &res) { mShininess = res.shininess; return true; } else { - // TODO - mFlags = mFlags & 0xFFFE; + ClearFlag4(); return false; } } diff --git a/src/m/m3d/m3d.cpp b/src/m/m3d/m3d.cpp index f6fa0f9f..f701c3c3 100644 --- a/src/m/m3d/m3d.cpp +++ b/src/m/m3d/m3d.cpp @@ -1,7 +1,9 @@ #include "m/m3d/m3d.h" #include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggFogManager.h" #include "egg/gfx/eggGfxEngine.h" +#include "egg/gfx/eggLightManager.h" #include "egg/gfx/eggLightTexture.h" #include "egg/gfx/eggLightTextureMgr.h" #include "egg/gfx/eggScreen.h" @@ -13,6 +15,7 @@ #include "nw4r/g3d/g3d_state.h" #include "nw4r/g3d/res/g3d_resmat.h" #include "nw4r/g3d/res/g3d_resmdl.h" + #include "rvl/GX.h" // IWYU pragma: export namespace m3d { From fb8a02193562bf57d35c4c70d168c6ae226084a6 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 23 Mar 2025 00:17:07 +0100 Subject: [PATCH 32/62] fix --- src/toBeSorted/arc_callback_handler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/toBeSorted/arc_callback_handler.cpp b/src/toBeSorted/arc_callback_handler.cpp index eb51d80d..f2016729 100644 --- a/src/toBeSorted/arc_callback_handler.cpp +++ b/src/toBeSorted/arc_callback_handler.cpp @@ -2,6 +2,7 @@ #include "d/col/bg/d_bg_w_kcol.h" #include "d/d_rawarchive.h" #include "egg/gfx/eggLightTextureMgr.h" +#include "egg/gfx/eggLightManager.h" #include "m/m3d/m3d.h" #include "nw4r/g3d.h" // IWYU pragma: export #include "toBeSorted/arc_managers/current_stage_arc_manager.h" From f66c22cf63529120697765e05b796d401c16555f Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sat, 22 Mar 2025 20:47:12 -0400 Subject: [PATCH 33/62] eggDrawPathLightMap OK --- config/SOUE01/splits.txt | 4 +- config/SOUE01/symbols.txt | 26 ++-- configure.py | 2 +- include/egg/gfx/eggCapTexture.h | 11 +- include/egg/gfx/eggDrawGX.h | 5 +- include/egg/gfx/eggDrawPathBase.h | 6 +- include/egg/gfx/eggDrawPathDOF.h | 2 +- include/egg/gfx/eggDrawPathLightMap.h | 36 +++++ include/egg/gfx/eggDrawPathUnk2.h | 6 - include/egg/gfx/eggGlobalDrawState.h | 19 +++ include/egg/gfx/eggScreenEffectBase.h | 10 +- src/egg/gfx/eggDrawPathBase.cpp | 4 +- src/egg/gfx/eggDrawPathDOF.cpp | 2 +- src/egg/gfx/eggDrawPathLightMap.cpp | 194 ++++++++++++++++++++++++++ src/egg/gfx/eggDrawPathUnk2.cpp | 3 - 15 files changed, 295 insertions(+), 35 deletions(-) create mode 100644 include/egg/gfx/eggDrawPathLightMap.h delete mode 100644 include/egg/gfx/eggDrawPathUnk2.h create mode 100644 src/egg/gfx/eggDrawPathLightMap.cpp delete mode 100644 src/egg/gfx/eggDrawPathUnk2.cpp diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 65ba25c3..a2cd5733 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2213,8 +2213,10 @@ egg/gfx/eggDrawPathDOF.cpp: .text start:0x804A29C0 end:0x804A4BE8 .data start:0x8056EF28 end:0x8056EFA0 -egg/gfx/eggDrawPathUnk2.cpp: +egg/gfx/eggDrawPathLightMap.cpp: .text start:0x804A4BF0 end:0x804A54E8 + .data start:0x8056EFA0 end:0x8056EFF0 + .sdata2 start:0x8057F5F8 end:0x8057F608 egg/gfx/eggFog.cpp: .text start:0x804A54F0 end:0x804A5A08 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index b54e015c..887e80fb 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -9796,8 +9796,8 @@ setMaterialInternal__Q23EGG14PostEffectBaseFv = .text:0x80174920; // type:functi fn_80174930 = .text:0x80174930; // type:function size:0x8 fn_80174940 = .text:0x80174940; // type:function size:0x14 fn_80174960 = .text:0x80174960; // type:function size:0x8 -@8@scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x80174970; // type:function size:0x8 -@20@ExecCallback_CALC_VIEW__Q23EGG12DrawPathBaseFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x80174980; // type:function size:0x8 +@8@scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x80174970; // type:function size:0x8 scope:weak +@20@ExecCallback_CALC_VIEW__Q23EGG12DrawPathBaseFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x80174980; // type:function size:0x8 scope:weak fn_80174990 = .text:0x80174990; // type:function size:0x8 fn_801749A0 = .text:0x801749A0; // type:function size:0x8 fn_801749B0 = .text:0x801749B0; // type:function size:0x8 @@ -10535,7 +10535,7 @@ fn_80197F50 = .text:0x80197F50; // type:function size:0x5C fn_80197FB0 = .text:0x80197FB0; // type:function size:0x5C fn_80198010 = .text:0x80198010; // type:function size:0x60 fn_80198070 = .text:0x80198070; // type:function size:0x64 -EGG__DrawPathShadowVolume____dt = .text:0x801980E0; // type:function size:0x60 +__dt__Q23EGG16DrawPathLightMapFv = .text:0x801980E0; // type:function size:0x60 scope:weak fn_80198140 = .text:0x80198140; // type:function size:0x58 fn_801981A0 = .text:0x801981A0; // type:function size:0x58 fn_80198200 = .text:0x80198200; // type:function size:0x58 @@ -10646,7 +10646,7 @@ addArcnToStage = .text:0x8019BF80; // type:function size:0x17C ArcnObjnManager__doLoad = .text:0x8019C100; // type:function size:0x64 ArcnObjnManager__checkLoaded = .text:0x8019C170; // type:function size:0x44 fn_8019C1C0 = .text:0x8019C1C0; // type:function size:0x44 -fn_8019C210 = .text:0x8019C210; // type:function size:0x8 +getNumStep__Q23EGG16DrawPathLightMapCFv = .text:0x8019C210; // type:function size:0x8 scope:weak fn_8019C220 = .text:0x8019C220; // type:function size:0x4 fn_8019C230 = .text:0x8019C230; // type:function size:0x4 fn_8019C240 = .text:0x8019C240; // type:function size:0x4 @@ -26482,8 +26482,8 @@ __ct__Q23EGG12DrawPathBaseFv = .text:0x804A0C30; // type:function size:0x58 createScnProc__Q23EGG12DrawPathBaseFP12MEMAllocator = .text:0x804A0C90; // type:function size:0x1B0 ExecCallback_CALC_VIEW__Q23EGG12DrawPathBaseFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x804A0E40; // type:function size:0x20 scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x804A0E60; // type:function size:0x20 -@8@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E80; // type:function size:0x8 -@20@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E90; // type:function size:0x8 +@8@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E80; // type:function size:0x8 scope:weak +@20@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E90; // type:function size:0x8 scope:weak FUN_804a0ea0 = .text:0x804A0EA0; // type:function size:0x188 __dt__Q23EGG14PostEffectMaskFv = .text:0x804A1030; // type:function size:0x40 __dt__Q23EGG14PostEffectUnk1Fv = .text:0x804A1070; // type:function size:0x40 @@ -26514,12 +26514,12 @@ SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3BinRC @8@__dt__Q23EGG11DrawPathDOFFv = .text:0x804A4BC0; // type:function size:0x8 @20@__dt__Q23EGG11DrawPathDOFFv = .text:0x804A4BD0; // type:function size:0x8 @24@__dt__Q23EGG11DrawPathDOFFv = .text:0x804A4BE0; // type:function size:0x8 -EGG__DrawPathShadowVolume____ct = .text:0x804A4BF0; // type:function size:0x7C -FUN_804a4c70 = .text:0x804A4C70; // type:function size:0x3C -EGG__DrawPathShadowVolume__internalDraw = .text:0x804A4CB0; // type:function size:0x7B4 -FUN_804a5470 = .text:0x804A5470; // type:function size:0x5C -EGG__DrawPathShadowVolume__8__dt = .text:0x804A54D0; // type:function size:0x8 -EGG__DrawPathShadowVolume__20__dt = .text:0x804A54E0; // type:function size:0x8 +__ct__Q23EGG16DrawPathLightMapFv = .text:0x804A4BF0; // type:function size:0x7C +internalResetForDraw__Q23EGG16DrawPathLightMapFv = .text:0x804A4C70; // type:function size:0x3C +internalDraw__Q23EGG16DrawPathLightMapFUs = .text:0x804A4CB0; // type:function size:0x7B4 +freeTextureBuffers__Q23EGG16DrawPathLightMapFv = .text:0x804A5470; // type:function size:0x5C +@8@__dt__Q23EGG16DrawPathLightMapFv = .text:0x804A54D0; // type:function size:0x8 scope:weak +@20@__dt__Q23EGG16DrawPathLightMapFv = .text:0x804A54E0; // type:function size:0x8 scope:weak GetBinaryType__Q23EGG19IBinaryFv = .text:0x804A54F0; // type:function size:0x8 GetVersion__Q23EGG19IBinaryFv = .text:0x804A5500; // type:function size:0x8 __ct__Q23EGG3FogFv = .text:0x804A5510; // type:function size:0x3C @@ -37363,7 +37363,7 @@ jumptable_8056EE18 = .data:0x8056EE18; // type:object size:0x48 scope:local __vt__Q23EGG12DrawPathBase = .data:0x8056EE60; // type:object size:0x50 lbl_8056EEB0 = .data:0x8056EEB0; // type:object size:0x78 __vt__Q23EGG11DrawPathDOF = .data:0x8056EF28; // type:object size:0x78 -lbl_8056EFA0 = .data:0x8056EFA0; // type:object size:0x50 +__vt__Q23EGG16DrawPathLightMap = .data:0x8056EFA0; // type:object size:0x50 __vt__Q23EGG3Fog = .data:0x8056EFF0; // type:object size:0x20 __vt__Q23EGG10FogManager = .data:0x8056F010; // type:object size:0x1C __vt__Q23EGG7Frustum = .data:0x8056F030; // type:object size:0x14 diff --git a/configure.py b/configure.py index c41aa5db..34797012 100644 --- a/configure.py +++ b/configure.py @@ -875,7 +875,7 @@ config.libs = [ Object(Matching, "egg/gfx/eggDrawPathBase.cpp"), Object(NonMatching, "egg/gfx/eggDrawPathUnk1.cpp"), Object(NonMatching, "egg/gfx/eggDrawPathDOF.cpp"), - Object(NonMatching, "egg/gfx/eggDrawPathUnk2.cpp"), + Object(Matching, "egg/gfx/eggDrawPathLightMap.cpp"), Object(NonMatching, "egg/gfx/eggFog.cpp"), Object(NonMatching, "egg/gfx/eggFogManager.cpp"), Object(NonMatching, "egg/gfx/eggFrustum.cpp"), diff --git a/include/egg/gfx/eggCapTexture.h b/include/egg/gfx/eggCapTexture.h index cedc5ce1..bf6d1f7b 100644 --- a/include/egg/gfx/eggCapTexture.h +++ b/include/egg/gfx/eggCapTexture.h @@ -12,8 +12,8 @@ struct CopyFilter { class CapTexture : public CpuTexture { public: CapTexture() {} - CapTexture(u16 width, u16 height, GXTexFmt texFmt): CpuTexture(width, height, texFmt) {} - CapTexture(const GXTexObj *pObj): CpuTexture(pObj) {} + CapTexture(u16 width, u16 height, GXTexFmt texFmt) : CpuTexture(width, height, texFmt) {} + CapTexture(const GXTexObj *pObj) : CpuTexture(pObj) {} virtual void configure() override; // at 0xC @@ -27,6 +27,13 @@ public: } } + void onCapFlag(u8 flag) { + mCapFlags |= flag; + } + void offCapFlag(u8 flag) { + mCapFlags &= ~flag; + } + void setClearColor(const GXColor &clr) { mClearColor = clr; } diff --git a/include/egg/gfx/eggDrawGX.h b/include/egg/gfx/eggDrawGX.h index 6854ab50..7a4056b6 100644 --- a/include/egg/gfx/eggDrawGX.h +++ b/include/egg/gfx/eggDrawGX.h @@ -151,8 +151,11 @@ public: 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); + static void DrawDLWorld(DL dl, const EGG::Matrix34f &mtx, GXColor color); + static void DrawDL16(const nw4r::math::MTX34 &mtx, GXColor clr) { + DrawDL(DL_16, mtx, clr); + } // TODO MORE // not sure diff --git a/include/egg/gfx/eggDrawPathBase.h b/include/egg/gfx/eggDrawPathBase.h index 8925785b..f1e91613 100644 --- a/include/egg/gfx/eggDrawPathBase.h +++ b/include/egg/gfx/eggDrawPathBase.h @@ -17,12 +17,12 @@ public: protected: virtual u16 getNumStep() const = 0; // at 0x3C virtual void internalResetForDraw() {} // at 0x40 - virtual void internalDraw() = 0; // at 0x44 + virtual void internalDraw(u16) = 0; // at 0x44 virtual void ExecCallback_CALC_VIEW( nw4r::g3d::ScnObj::Timing /* timing */, nw4r::g3d::ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */ - ) override; // also at 0x48 - virtual void scnProcDraw(u16) override; // also at 0x4C + ) override; // also at 0x48 + virtual void scnProcDraw(u16) override; // also at 0x4C }; } // namespace EGG diff --git a/include/egg/gfx/eggDrawPathDOF.h b/include/egg/gfx/eggDrawPathDOF.h index 3e523d45..ae1cce6c 100644 --- a/include/egg/gfx/eggDrawPathDOF.h +++ b/include/egg/gfx/eggDrawPathDOF.h @@ -18,7 +18,7 @@ public: return 3; } virtual void internalResetForDraw() override; - virtual void internalDraw() override; + virtual void internalDraw(u16) override; virtual void SetBinaryInner(const Bin &) override; virtual void GetBinaryInner(Bin *) const override; diff --git a/include/egg/gfx/eggDrawPathLightMap.h b/include/egg/gfx/eggDrawPathLightMap.h new file mode 100644 index 00000000..9fed2ac8 --- /dev/null +++ b/include/egg/gfx/eggDrawPathLightMap.h @@ -0,0 +1,36 @@ +#ifndef EGG_DRAW_PATH_LIGHTMAP_H +#define EGG_DRAW_PATH_LIGHTMAP_H + +#include "egg/gfx/eggDrawPathBase.h" +#include "egg/gfx/eggTextureBuffer.h" + +namespace EGG { + +// A guess based of what is seen in ogws. Has been Updated +class DrawPathLightMap : public DrawPathBase { +public: + DrawPathLightMap(); + + virtual u16 getNumStep() const override { + return 3; + } + virtual void internalResetForDraw() override; + virtual void internalDraw(u16) override; + virtual ~DrawPathLightMap(); + void freeTextureBuffers(); + +private: + /* 0x18 */ u8 field_0x18; + /* 0x19 */ u8 mAlpha; + /* 0x1C */ int field_0x1C; + /* 0x20 */ int field_0x20; + /* 0x24 */ u32 field_0x24; + /* 0x28 */ TextureBuffer *mpTextureBuffer_0x28; + /* 0x2C */ TextureBuffer *mpTextureBuffer_0x2C; + /* 0x30 */ TextureBuffer *mpTextureBuffer_0x30; + /* 0x34 */ u32 mOldDrawFlag; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggDrawPathUnk2.h b/include/egg/gfx/eggDrawPathUnk2.h deleted file mode 100644 index 3b04c908..00000000 --- a/include/egg/gfx/eggDrawPathUnk2.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef EGG_DRAW_PATH_UNK2_H -#define EGG_DRAW_PATH_UNK2_H - -namespace EGG {} // namespace EGG - -#endif diff --git a/include/egg/gfx/eggGlobalDrawState.h b/include/egg/gfx/eggGlobalDrawState.h index 11c070ec..a85dfbb6 100644 --- a/include/egg/gfx/eggGlobalDrawState.h +++ b/include/egg/gfx/eggGlobalDrawState.h @@ -12,6 +12,25 @@ public: static void setDrawSettingGX(bool, bool); static void beginDrawView(u16, nw4r::math::MTX34 const &, Screen const &); + static const Screen &getScreen() { + return *spScreen; + } + static void setScreen(const Screen &screen) { + spScreen = &screen; + } + static u32 getDrawFlag() { + return sDrawFlag; + } + static void setDrawFlag(u32 flag) { + sDrawFlag = flag; + } + static void onDrawFlag(u32 flag) { + sDrawFlag |= flag; + } + static void offDrawFlag(u32 flag) { + sDrawFlag &= ~flag; + } + private: static u16 sCameraId; static u32 sDrawFlag; diff --git a/include/egg/gfx/eggScreenEffectBase.h b/include/egg/gfx/eggScreenEffectBase.h index b90c4df7..09f44699 100644 --- a/include/egg/gfx/eggScreenEffectBase.h +++ b/include/egg/gfx/eggScreenEffectBase.h @@ -8,12 +8,20 @@ namespace EGG { class ScreenEffectBase { protected: - u8 mFlag; + /* 0x0 */ u8 mFlag; public: ScreenEffectBase(); virtual ~ScreenEffectBase() {} // at 0x8 + static Screen &GetScreen() { + return sScreen; + } + + bool isFlag0x2() const { + return mFlag & 2; + } + protected: static Screen sScreen; }; diff --git a/src/egg/gfx/eggDrawPathBase.cpp b/src/egg/gfx/eggDrawPathBase.cpp index de88310e..3a98067f 100644 --- a/src/egg/gfx/eggDrawPathBase.cpp +++ b/src/egg/gfx/eggDrawPathBase.cpp @@ -35,9 +35,9 @@ void DrawPathBase::ExecCallback_CALC_VIEW( } } -void DrawPathBase::scnProcDraw(u16) { +void DrawPathBase::scnProcDraw(u16 idx) { if (mFlag & 1) { - internalDraw(); + internalDraw(idx); } } diff --git a/src/egg/gfx/eggDrawPathDOF.cpp b/src/egg/gfx/eggDrawPathDOF.cpp index 588f02ba..11413838 100644 --- a/src/egg/gfx/eggDrawPathDOF.cpp +++ b/src/egg/gfx/eggDrawPathDOF.cpp @@ -6,7 +6,7 @@ DrawPathDOF::DrawPathDOF() {} DrawPathDOF::~DrawPathDOF() {} -void DrawPathDOF::internalDraw() {} +void DrawPathDOF::internalDraw(u16) {} void DrawPathDOF::internalResetForDraw() {} diff --git a/src/egg/gfx/eggDrawPathLightMap.cpp b/src/egg/gfx/eggDrawPathLightMap.cpp new file mode 100644 index 00000000..21a0ad6c --- /dev/null +++ b/src/egg/gfx/eggDrawPathLightMap.cpp @@ -0,0 +1,194 @@ +#include "egg/gfx/eggDrawPathLightMap.h" + +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggGlobalDrawState.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "egg/gfx/eggStateGX.h" +#include "rvl/GX/GXPixel.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +DrawPathLightMap::DrawPathLightMap() + : field_0x18(6), + mAlpha(0xFF), + field_0x1C(0), + field_0x20(0), + field_0x24(0), + mpTextureBuffer_0x28(nullptr), + mpTextureBuffer_0x2C(nullptr), + mpTextureBuffer_0x30(nullptr), + mOldDrawFlag(0) {} + +void DrawPathLightMap::internalResetForDraw() { + freeTextureBuffers(); + mpTextureBuffer_0x28 = nullptr; + mpTextureBuffer_0x2C = nullptr; + mpTextureBuffer_0x30 = nullptr; +} + +void DrawPathLightMap::internalDraw(u16 idx) { + const Screen::DataEfb &efb = GlobalDrawState::getScreen().GetDataEfb(); + + switch (idx) { + case 0: { + if (field_0x18 & 1) { + mpTextureBuffer_0x30 = TextureBuffer::alloc(efb.vp.x2, efb.vp.y2, GX_TF_RGBA8); + mpTextureBuffer_0x30->onCapFlag(1); + mpTextureBuffer_0x30->onCapFlag(2); + mpTextureBuffer_0x30->setFilt(GX_NEAR, GX_NEAR); + mpTextureBuffer_0x30->capture(efb.vp.x1, efb.vp.y1, false, -1); + } + mOldDrawFlag = GlobalDrawState::getDrawFlag(); + GlobalDrawState::onDrawFlag(0x1 | 0x2); + } break; + case 1: { + GlobalDrawState::setDrawFlag(mOldDrawFlag); + GXTexFmt fmt = GX_TF_RGBA8; + + if (field_0x20 == 1) { + fmt = GX_TF_RGB5A3; + if (field_0x1C == 1) { + fmt = GX_TF_RGB565; + } + } + + int capW = efb.vp.x1; + int capH = efb.vp.y1; + + mpTextureBuffer_0x28 = TextureBuffer::alloc(efb.vp.x2, efb.vp.y2, fmt); + + mpTextureBuffer_0x28->onCapFlag(1); + mpTextureBuffer_0x28->onCapFlag(2); + if (!(field_0x18 & 2)) { + mpTextureBuffer_0x28->onCapFlag(4); + } + mpTextureBuffer_0x28->setClearColor(StateGX::getClearEfb()); + + mpTextureBuffer_0x28->capture(capW, capH, false, -1); + mpTextureBuffer_0x28->setFilt(GX_NEAR, GX_NEAR); + + if (mpTextureBuffer_0x30) { + nw4r::math::MTX34 forDL; + + StateGX::ScopedColor _color(true); + StateGX::ScopedAlpha _alpha(true); + StateGX::ScopedDither _dither(false); + + PostEffectBase::setProjection(GetScreen()); + + PSMTXScale(forDL, GetScreen().GetWidth(), GetScreen().GetHeight(), 1.0f); + + mpTextureBuffer_0x30->load(GX_TEXMAP0); + DrawGX::BeginDrawScreen(true, true, false); + + DrawGX::SetBlendMode(DrawGX::BLEND_14); + + DrawGX::DrawDL16(forDL, DrawGX::WHITE); + + mpTextureBuffer_0x30->free(); + mpTextureBuffer_0x30 = nullptr; + } + + if (field_0x18 & 2) { + mpTextureBuffer_0x2C = TextureBuffer::alloc(efb.vp.x2, efb.vp.y2, GX_TF_Z24X8); + mpTextureBuffer_0x2C->onCapFlag(4); + + if (isFlag0x2()) { + mpTextureBuffer_0x2C->onCapFlag(0x10); + } else { + mpTextureBuffer_0x2C->offCapFlag(0x10); + } + + mpTextureBuffer_0x2C->capture(capW, capH, false, -1); + mpTextureBuffer_0x2C->setFilt(GX_NEAR, GX_NEAR); + } + StateGX::invalidateTexAllGX(); + } break; + case 2: { + if (mpTextureBuffer_0x28) { + if (mAlpha != 0) { + mpTextureBuffer_0x28->load(GX_TEXMAP0); + + nw4r::math::MTX34 forDL; + PostEffectBase::setProjection(GetScreen()); + PSMTXScale(forDL, GetScreen().GetWidth(), GetScreen().GetHeight(), 1.0f); + + GXColor tevColor = {0xFF, 0xFF, 0xFF, mAlpha}; + + StateGX::ScopedColor _color(true); + StateGX::ScopedAlpha _alpha(false); + StateGX::ScopedDither _dither(true); + + if (mpTextureBuffer_0x2C) { + mpTextureBuffer_0x2C->load(GX_TEXMAP1); + DrawGX::SetMat_ColorChannel(DrawGX::COLORCHAN_1); + DrawGX::SetMat_TexGen(DrawGX::TEXGEN_1); + DrawGX::SetMat_Ind(); + GXSetTevKColor(GX_KCOLOR0, (GXColor){0}); + + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetNumTevStages(2); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevDirect(GX_TEVSTAGE1); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + + if (field_0x1C == 0) { + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_TEXA, GX_CA_KONST, GX_CA_RASA, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_COMP_A8_GT, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + } else { + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + 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_RASA); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + } + + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_CPREV); + 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_APREV); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetZTexture(GZ_ZT_REPLACE, GX_TF_Z24X8, 0); + + GXSetZMode(true, field_0x1C == 0 ? GX_LEQUAL : GX_LESS, field_0x18 & 0x4 ? true : false); + GXSetZCompLoc(0); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + DrawGX::SetBlendMode(DrawGX::BLEND_0); + DrawGX::SetVtxState(DrawGX::VTX_TYPE_11); + } else { + DrawGX::BeginDrawScreen(true, true, false); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_TEXA, GX_CA_ZERO, GX_CA_RASA, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_COMP_A8_GT, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + } + + DrawGX::DrawDL16(forDL, tevColor); + GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z24X8, 0); + } + freeTextureBuffers(); + } + } break; + } +} + +void DrawPathLightMap::freeTextureBuffers() { + if (mpTextureBuffer_0x2C) { + mpTextureBuffer_0x2C->free(); + mpTextureBuffer_0x2C = nullptr; + } + if (mpTextureBuffer_0x28) { + mpTextureBuffer_0x28->free(); + mpTextureBuffer_0x28 = nullptr; + } +} + +} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathUnk2.cpp b/src/egg/gfx/eggDrawPathUnk2.cpp deleted file mode 100644 index eb4f9c5d..00000000 --- a/src/egg/gfx/eggDrawPathUnk2.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "egg/gfx/eggDrawPathUnk2.h" - -namespace EGG {} // namespace EGG From 115d0d706594bbf1f5dab1b82da0f0e4981b0571 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sun, 23 Mar 2025 11:56:25 -0400 Subject: [PATCH 34/62] Post Effect Progress. PostEffectBlurGather OK --- config/SOUE01/splits.txt | 8 +- config/SOUE01/symbols.txt | 8 +- configure.py | 4 +- include/egg/gfx/eggDrawPathBloom.h | 20 +++++ include/egg/gfx/eggDrawPathUnk1.h | 6 -- include/egg/gfx/eggPostEffectBlurGather.h | 40 +++++++++ include/egg/gfx/eggPostEffectUnk1.h | 31 ------- include/egg/gfx/eggPostEffectUnk2.h | 6 +- include/egg/math/eggVector.h | 1 + src/egg/gfx/eggDrawPathBloom.cpp | 3 + src/egg/gfx/eggDrawPathUnk1.cpp | 3 - ...ctUnk1.cpp => eggPostEffectBlurGather.cpp} | 23 ++--- src/egg/gfx/eggPostEffectMask.cpp | 4 +- src/egg/gfx/eggPostEffectUnk2.cpp | 85 ++++++++++--------- 14 files changed, 131 insertions(+), 111 deletions(-) create mode 100644 include/egg/gfx/eggDrawPathBloom.h delete mode 100644 include/egg/gfx/eggDrawPathUnk1.h create mode 100644 include/egg/gfx/eggPostEffectBlurGather.h delete mode 100644 include/egg/gfx/eggPostEffectUnk1.h create mode 100644 src/egg/gfx/eggDrawPathBloom.cpp delete mode 100644 src/egg/gfx/eggDrawPathUnk1.cpp rename src/egg/gfx/{eggPostEffectUnk1.cpp => eggPostEffectBlurGather.cpp} (85%) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index e0db061e..029195de 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2206,7 +2206,7 @@ egg/gfx/eggDrawPathBase.cpp: .text start:0x804A0C30 end:0x804A0E98 .data start:0x8056EE60 end:0x8056EEB0 -egg/gfx/eggDrawPathUnk1.cpp: +egg/gfx/eggDrawPathBloom.cpp: .text start:0x804A0EA0 end:0x804A29B8 egg/gfx/eggDrawPathDOF.cpp: @@ -2296,16 +2296,16 @@ egg/gfx/eggPostEffectBlur.cpp: .data start:0x8056F170 end:0x8056F190 .sdata2 start:0x8057F750 end:0x8057F788 -egg/gfx/eggPostEffectUnk1.cpp: +egg/gfx/eggPostEffectBlurGather.cpp: .text start:0x804AFC10 end:0x804B0098 - .data start:0x8056F190 end:0x8056F1B0 + .data start:0x8056F190 end:0x8056F1AC .sdata2 start:0x8057F788 end:0x8057F798 egg/gfx/eggPostEffectUnk2.cpp: .text start:0x804B00A0 end:0x804B0AA4 .rodata start:0x804FBD50 end:0x804FBD88 .data start:0x8056F1B0 end:0x8056F1D0 - .sdata2 start:0x8057F798 end:0x8057F7C8 + .sdata2 start:0x8057F798 end:0x8057F7C4 egg/gfx/eggPostEffectMask.cpp: .text start:0x804B0AB0 end:0x804B0F60 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 93a856f0..cd6d5f2a 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26486,7 +26486,7 @@ scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x804A0E60; // type:function size:0 @20@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E90; // type:function size:0x8 scope:weak FUN_804a0ea0 = .text:0x804A0EA0; // type:function size:0x188 __dt__Q23EGG14PostEffectMaskFv = .text:0x804A1030; // type:function size:0x40 -__dt__Q23EGG14PostEffectUnk1Fv = .text:0x804A1070; // type:function size:0x40 +__dt__Q23EGG20PostEffectBlurGatherFv = .text:0x804A1070; // type:function size:0x40 __dt__Q23EGG16PostEffectSimpleFv = .text:0x804A10B0; // type:function size:0x40 FUN_804a10f0 = .text:0x804A10F0; // type:function size:0x60 FUN_804a1150 = .text:0x804A1150; // type:function size:0x21C @@ -26705,8 +26705,8 @@ setProjection__Q23EGG14PostEffectBaseFRCQ23EGG6Screen = .text:0x804AF3C0; // typ __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 +__ct__Q23EGG20PostEffectBlurGatherFv = .text:0x804AFC10; // type:function size:0xC0 +setMaterialInternal__Q23EGG20PostEffectBlurGatherFv = .text:0x804AFCD0; // type:function size:0x3C8 __ct__Q23EGG14PostEffectUnk2Fv = .text:0x804B00A0; // type:function size:0x1F8 __dt__Q23EGG14PostEffectUnk2Fv = .text:0x804B02A0; // type:function size:0x80 draw__Q23EGG14PostEffectUnk2Fff = .text:0x804B0320; // type:function size:0x2D4 @@ -37377,7 +37377,7 @@ 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 __vt__Q23EGG14PostEffectBlur = .data:0x8056F170; // type:object size:0x1C -__vt__Q23EGG14PostEffectUnk1 = .data:0x8056F190; // type:object size:0x20 +__vt__Q23EGG20PostEffectBlurGather = .data:0x8056F190; // type:object size:0x1C __vt__Q23EGG14PostEffectUnk2 = .data:0x8056F1B0; // type:object size:0x1C __vt__Q23EGG14PostEffectMask = .data:0x8056F1D0; // type:object size:0x1C lbl_8056F1F0 = .data:0x8056F1F0; // type:object size:0x1C diff --git a/configure.py b/configure.py index 34797012..83c05073 100644 --- a/configure.py +++ b/configure.py @@ -873,7 +873,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggCpuTexture.cpp"), Object(NonMatching, "egg/gfx/eggDrawGX.cpp"), Object(Matching, "egg/gfx/eggDrawPathBase.cpp"), - Object(NonMatching, "egg/gfx/eggDrawPathUnk1.cpp"), + Object(NonMatching, "egg/gfx/eggDrawPathBloom.cpp"), Object(NonMatching, "egg/gfx/eggDrawPathDOF.cpp"), Object(Matching, "egg/gfx/eggDrawPathLightMap.cpp"), Object(NonMatching, "egg/gfx/eggFog.cpp"), @@ -891,7 +891,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggModelEx.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectBase.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectBlur.cpp"), - Object(NonMatching, "egg/gfx/eggPostEffectUnk1.cpp"), # Unknown + Object(Matching, "egg/gfx/eggPostEffectBlurGather.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectUnk2.cpp"), # Unknown Object(Matching, "egg/gfx/eggPostEffectMask.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectMaskDOF.cpp"), diff --git a/include/egg/gfx/eggDrawPathBloom.h b/include/egg/gfx/eggDrawPathBloom.h new file mode 100644 index 00000000..7f0b0f30 --- /dev/null +++ b/include/egg/gfx/eggDrawPathBloom.h @@ -0,0 +1,20 @@ +#ifndef EGG_DRAW_PATH_BLOOM_H +#define EGG_DRAW_PATH_BLOOM_H + +#include "egg/gfx/eggDrawPathBase.h" +namespace EGG { + +class DrawPathBloom : public DrawPathBase { +public: + virtual ~DrawPathBloom(); + + virtual u16 getNumStep() const override { + return 3; + } + +private: +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggDrawPathUnk1.h b/include/egg/gfx/eggDrawPathUnk1.h deleted file mode 100644 index 4b2c3cc7..00000000 --- a/include/egg/gfx/eggDrawPathUnk1.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef EGG_DRAW_PATH_UNK1_H -#define EGG_DRAW_PATH_UNK1_H - -namespace EGG {} // namespace EGG - -#endif diff --git a/include/egg/gfx/eggPostEffectBlurGather.h b/include/egg/gfx/eggPostEffectBlurGather.h new file mode 100644 index 00000000..9a1966d7 --- /dev/null +++ b/include/egg/gfx/eggPostEffectBlurGather.h @@ -0,0 +1,40 @@ +#ifndef EGG_POST_EFFECT_BLUR_GATHER_H +#define EGG_POST_EFFECT_BLUR_GATHER_H + +#include "common.h" +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +class PostEffectBlurGather : public PostEffectBase { + // Size 0x18 + struct BlurGatherData { + void reset() { + mpCapTexture = nullptr; + mColor = DrawGX::WHITE; + mColorScale = 1.f; + field_0x10 = 0; + } + /* 0x00 */ EGG::CpuTexture *mpCapTexture; + /* 0x04 */ GXTexMapID mTexMapId; + /* 0x08 */ GXColor mColor; + /* 0x0C */ f32 mColorScale; + /* 0x10 */ u8 field_0x10; + }; + +public: + PostEffectBlurGather(); + virtual void setMaterialInternal() override; + + /* 0x2C */ u8 field_0x2C; + /* 0x2D */ u8 field_0x2D; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ BlurGatherData mBlurGatherData[3]; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggPostEffectUnk1.h b/include/egg/gfx/eggPostEffectUnk1.h deleted file mode 100644 index e2a6c03b..00000000 --- a/include/egg/gfx/eggPostEffectUnk1.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef EGG_POST_EFFECT_UNK1_H -#define EGG_POST_EFFECT_UNK1_H - -#include "egg/gfx/eggCpuTexture.h" -#include "egg/gfx/eggPostEffectBase.h" -#include "rvl/GX/GXTypes.h" -namespace EGG { - -class PostEffectUnk1 : public PostEffectBase { - // Size 0x18 - 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 */ Stage field_0x34[3]; -}; - -} // namespace EGG - -#endif diff --git a/include/egg/gfx/eggPostEffectUnk2.h b/include/egg/gfx/eggPostEffectUnk2.h index 64173db6..8cd8ac97 100644 --- a/include/egg/gfx/eggPostEffectUnk2.h +++ b/include/egg/gfx/eggPostEffectUnk2.h @@ -3,6 +3,7 @@ #include "egg/egg_types.h" #include "egg/gfx/eggPostEffectBase.h" +#include "egg/math/eggVector.h" namespace EGG { @@ -14,13 +15,12 @@ public: virtual void setMaterialInternal() override; private: - /* 0x2C */ s32 field_0x2C; + /* 0x2C */ u32 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; + /* 0x38 */ Vector2f field_0x38; /* 0x40 */ f32 field_0x40; /* 0x44 */ f32 field_0x44; /* 0x48 */ f32 field_0x48; diff --git a/include/egg/math/eggVector.h b/include/egg/math/eggVector.h index 3fa0c871..2d030d45 100644 --- a/include/egg/math/eggVector.h +++ b/include/egg/math/eggVector.h @@ -3,6 +3,7 @@ #include "common.h" #include "egg/math/eggMath.h" +#include "nw4r/math/math_triangular.h" #include "nw4r/math.h" diff --git a/src/egg/gfx/eggDrawPathBloom.cpp b/src/egg/gfx/eggDrawPathBloom.cpp new file mode 100644 index 00000000..5a42210b --- /dev/null +++ b/src/egg/gfx/eggDrawPathBloom.cpp @@ -0,0 +1,3 @@ +#include "egg/gfx/eggDrawPathBloom.h" + +namespace EGG {} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathUnk1.cpp b/src/egg/gfx/eggDrawPathUnk1.cpp deleted file mode 100644 index 2a89d9da..00000000 --- a/src/egg/gfx/eggDrawPathUnk1.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "egg/gfx/eggDrawPathUnk1.h" - -namespace EGG {} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectUnk1.cpp b/src/egg/gfx/eggPostEffectBlurGather.cpp similarity index 85% rename from src/egg/gfx/eggPostEffectUnk1.cpp rename to src/egg/gfx/eggPostEffectBlurGather.cpp index ade510b4..0f01e6e1 100644 --- a/src/egg/gfx/eggPostEffectUnk1.cpp +++ b/src/egg/gfx/eggPostEffectBlurGather.cpp @@ -1,8 +1,7 @@ -#include "egg/gfx/eggPostEffectUnk1.h" +#include "egg/gfx/eggPostEffectBlurGather.h" #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" @@ -12,20 +11,16 @@ namespace EGG { -PostEffectUnk1::PostEffectUnk1() { - // NONMATCHING +PostEffectBlurGather::PostEffectBlurGather() { 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; - } + mBlurGatherData[0].reset(); + mBlurGatherData[1].reset(); + mBlurGatherData[2].reset(); } -void PostEffectUnk1::setMaterialInternal() { +void PostEffectBlurGather::setMaterialInternal() { u8 hasExtraStage = (mpCapTexture != nullptr && (field_0x2D & 1) == 0) ? 1 : 0; u8 numStages = field_0x2C + hasExtraStage * 2; setMatColorChannel(); @@ -37,7 +32,7 @@ void PostEffectUnk1::setMaterialInternal() { 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); + mBlurGatherData[i].mpCapTexture->load(mBlurGatherData[i].mTexMapId); } else { loadTextureInternal(); } @@ -50,13 +45,13 @@ void PostEffectUnk1::setMaterialInternal() { GXSetNumTevStages(numStages); for (int i = 0; i < numStages; i++) { - Stage &k = field_0x34[i]; + BlurGatherData &k = mBlurGatherData[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); + scaleColor(scaledColor, k.mColor, false, k.mColorScale); GXSetTevKColorSel(stage, static_cast(GX_TEV_KCSEL_K0 + i)); GXSetTevKAlphaSel(stage, static_cast(GX_TEV_KASEL_K0_A + i)); diff --git a/src/egg/gfx/eggPostEffectMask.cpp b/src/egg/gfx/eggPostEffectMask.cpp index 5162e3a7..06424a66 100644 --- a/src/egg/gfx/eggPostEffectMask.cpp +++ b/src/egg/gfx/eggPostEffectMask.cpp @@ -19,8 +19,8 @@ void PostEffectMask::setMaterialInternal() { setMatColorChannel(); GXSetNumTexGens(2); - GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); - GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX_IDENT, false, GX_DUALMTX_IDENT); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX_IDENT, false, GX_DUALMTX_IDENT); setMatInd(); GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); GXSetTevDirect(GX_TEVSTAGE0); diff --git a/src/egg/gfx/eggPostEffectUnk2.cpp b/src/egg/gfx/eggPostEffectUnk2.cpp index f61134cf..abf57b73 100644 --- a/src/egg/gfx/eggPostEffectUnk2.cpp +++ b/src/egg/gfx/eggPostEffectUnk2.cpp @@ -16,33 +16,32 @@ 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; +inline f32 GetColor(f32 x, u16 w) { + return nw4r::ut::Min(x / (w - 1), 1.f) * 0xFF; +} + +PostEffectUnk2::PostEffectUnk2() + : // NONMATCHING + field_0x2C(0), + field_0x30(0), + field_0x34(1), + field_0x35(0xFE), + field_0x36(7), + field_0x38(0.0f, 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); + u8 val = GetColor(x, mpTexture->getWidth()); + + mpTexture->setColor(x, y, (GXColor){val, val, val, val}); } } @@ -62,7 +61,7 @@ void PostEffectUnk2::draw(f32 width, f32 height) { GXSetVtxDesc(GX_VA_TEX1, GX_DIRECT); nw4r::math::MTX34 mtx; - PSMTXScale(mtx, mScaleX * width, mScaleY * height, 1.0f); + PSMTXScale(mtx, width * mScaleX, height * mScaleY, 1.0f); PSMTXTransApply(mtx, mtx, mOffsetX, mOffsetY, 0.0f); GXLoadPosMtxImm(mtx, 0); @@ -75,38 +74,40 @@ void PostEffectUnk2::draw(f32 width, f32 height) { {-1.0f, 1.0f}, }; - // TODO - f32 s1 = field_0x40 / mpCapTexture->getWidth(); - f32 s2 = field_0x40 / mpCapTexture->getHeight(); - f32 f = 0.0f; + const f32 s1 = field_0x40 / mpCapTexture->getWidth(); + const f32 s2 = field_0x40 / mpCapTexture->getHeight(); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { - EGG::Vector3f(0.0f, 0.0f, 0.0f); + f32 mtx[2][4]; + EGG::Vector3f a(0.f, 0.f, 0.f); + 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); + nw4r::math::SinCosRad(&sin, &cos, a.z); + + mtx[0][0] = cos; + mtx[0][1] = -sin; + mtx[0][2] = -cos * a.x + sin * a.y + a.x + (s1 * floats1[i][j]); + + mtx[1][0] = sin; + mtx[1][1] = cos; + mtx[1][2] = -sin * a.x - cos * a.y + a.y + (s2 * floats2[i][j]); + + mtx[1][3] = 0.f; + mtx[0][3] = 0.f; + GXLoadTexMtxImm(mtx, 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); + GXPosition2f32(field_0x38.x, field_0x38.y); GXPosition2u8(1, 1); - GXPosition2f32(field_0x38, field_0x3C); + GXPosition2f32(field_0x38.x, field_0x38.y); GXPosition2u8(2, 2); - GXPosition2f32(field_0x38, field_0x3C); + GXPosition2f32(field_0x38.x, field_0x38.y); GXPosition2u8(3, 3); - GXPosition2f32(field_0x38, field_0x3C); + GXPosition2f32(field_0x38.x, field_0x38.y); } } @@ -153,7 +154,7 @@ void PostEffectUnk2::setMaterialInternal() { GXSetTevSwapMode(GX_TEVSTAGE3, GX_TEV_SWAP0, GX_TEV_SWAP0); GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD_NULL, GX_TEXMAP1, GX_COLOR_NULL); - if (field_0x2C == 2) { + if ((int)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); From 3ef9b0df8b956bdb3f371ee118ef6dc881ea61e6 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sun, 23 Mar 2025 15:29:15 -0400 Subject: [PATCH 35/62] PostEffect Progress --- config/SOUE01/splits.txt | 4 + configure.py | 2 +- include/egg/gfx/eggPostEffectBase.h | 26 ++-- include/egg/gfx/eggPostEffectBlur.h | 8 +- include/egg/gfx/eggPostEffectMaskDOF.h | 35 ++++- src/egg/gfx/eggPostEffectBase.cpp | 31 ++-- src/egg/gfx/eggPostEffectBlur.cpp | 49 +++--- src/egg/gfx/eggPostEffectBlurGather.cpp | 4 +- src/egg/gfx/eggPostEffectMask.cpp | 12 +- src/egg/gfx/eggPostEffectMaskDOF.cpp | 195 +++++++++++++++++++++++- src/egg/gfx/eggPostEffectSimple.cpp | 2 +- src/egg/gfx/eggPostEffectUnk2.cpp | 10 +- 12 files changed, 301 insertions(+), 77 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 029195de..9c7b55a7 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2314,6 +2314,10 @@ egg/gfx/eggPostEffectMask.cpp: egg/gfx/eggPostEffectMaskDOF.cpp: .text start:0x804B0F60 end:0x804B1BE8 + .rodata start:0x804FBD88 end:0x804FBDA0 + .data start:0x8056F1F0 end:0x8056F20C + .sdata2 start:0x8057F7D0 end:0x8057F80C + .sbss2 start:0x8057FFC8 end:0x8057FFCC egg/gfx/eggPostEffectSimple.cpp: .text start:0x804B1BF0 end:0x804B1E58 diff --git a/configure.py b/configure.py index 83c05073..79cd5a4e 100644 --- a/configure.py +++ b/configure.py @@ -889,7 +889,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggLightTexture.cpp"), Object(NonMatching, "egg/gfx/eggLightTextureMgr.cpp"), Object(NonMatching, "egg/gfx/eggModelEx.cpp"), - Object(NonMatching, "egg/gfx/eggPostEffectBase.cpp"), + Object(Matching, "egg/gfx/eggPostEffectBase.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectBlur.cpp"), Object(Matching, "egg/gfx/eggPostEffectBlurGather.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectUnk2.cpp"), # Unknown diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index 84a533c9..0e940200 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -2,7 +2,9 @@ #define EGG_POST_EFFECT_BASE_H #include "common.h" -#include "egg/egg_types.h" +#include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggScreen.h" +#include "egg/math/eggMath.h" #include "nw4r/math/math_types.h" #include "rvl/GX/GXTypes.h" @@ -10,6 +12,10 @@ namespace EGG { class PostEffectBase { public: + struct CapTextureWrapper { + CapTexture *mpTex; + GXTexMapID mTexMapID; + }; void setField_0x00(u32 val) { field_0x00 = val; } @@ -17,16 +23,14 @@ public: static void setProjection(const EGG::Screen &screen); protected: - u32 field_0x00; // at 0x0 - CapTexture *mpCapTexture; // at 0x4 - GXTexMapID mTexMapId; // at 0x8 - CapTexture *mpCapTexture2; // at 0xC - GXTexMapID mTexMapId2; // at 0x10 - f32 mOffsetX; // at 0x14 - f32 mOffsetY; // at 0x18 - f32 mScaleX; // at 0x1C - f32 mScaleY; // at 0x20 - f32 mRotation; // at 0x24 + u32 field_0x00; // at 0x0 + CapTextureWrapper mTex1; // at 0x4 + CapTextureWrapper mTex2; // at 0xC + f32 mOffsetX; // at 0x14 + f32 mOffsetY; // at 0x18 + f32 mScaleX; // at 0x1C + f32 mScaleY; // at 0x20 + f32 mRotation; // at 0x24 PostEffectBase(); virtual ~PostEffectBase() {} // at 0x8 diff --git a/include/egg/gfx/eggPostEffectBlur.h b/include/egg/gfx/eggPostEffectBlur.h index 103a55af..35db7a39 100644 --- a/include/egg/gfx/eggPostEffectBlur.h +++ b/include/egg/gfx/eggPostEffectBlur.h @@ -15,11 +15,11 @@ class PostEffectBlur : public PostEffectBase { /* 0x08 */ f32 field_0x08; /* 0x0C */ f32 field_0x0C; - void init(GXColor clr) { + void init(const GXColor &clr) { field_0x00 = 16; field_0x01 = clr; - field_0x08 = 1.0f; - field_0x0C = 0.0f; + field_0x08 = 0.0f; + field_0x0C = 1.0f; } }; @@ -40,7 +40,7 @@ public: void setStage0Color(GXColor clr) { field_0x38[0].field_0x01 = clr; } - + void setStage0F(f32 f) { field_0x38[0].field_0x0C = f; } diff --git a/include/egg/gfx/eggPostEffectMaskDOF.h b/include/egg/gfx/eggPostEffectMaskDOF.h index cf6398f6..5faca35a 100644 --- a/include/egg/gfx/eggPostEffectMaskDOF.h +++ b/include/egg/gfx/eggPostEffectMaskDOF.h @@ -1,6 +1,39 @@ #ifndef EGG_POST_EFFECT_MASK_DOF_H #define EGG_POST_EFFECT_MASK_DOF_H -namespace EGG {} // namespace EGG +#include "egg/gfx/eggCpuTexture.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "egg/math/eggVector.h" +#include "rvl/GX/GXTypes.h" +namespace EGG { + +class PostEffectMaskDOF : public PostEffectBase { +public: + PostEffectMaskDOF(); + + void setUpGradation(); + virtual void draw(f32 width, f32 height) override; + virtual void setMaterialInternal() override; + virtual ~PostEffectMaskDOF() {} + + const GXColor &getNearColor(); + const GXColor &getFarColor(); + const GXColor &getCenterColor(); + +private: + /* 0x2C */ u8 field_0x2C; + /* 0x30 */ CpuTexture *mpCpuTexArr[3]; + /* 0x3C */ CpuTexture *mpCpuTex; + /* 0x40 */ u8 _40[4]; + /* 0x44 */ f32 field_0x44; + /* 0x48 */ f32 field_0x48; + /* 0x4C */ f32 field_0x4C; + /* 0x50 */ Vector2f field_0x50; + /* 0x58 */ u8 _58[4]; + /* 0x5C */ int mCpuTexArrIdx; + /* 0x60 */ int field_0x60; +}; + +} // namespace EGG #endif diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp index bf824907..2b2993d7 100644 --- a/src/egg/gfx/eggPostEffectBase.cpp +++ b/src/egg/gfx/eggPostEffectBase.cpp @@ -1,9 +1,9 @@ #include "egg/gfx/eggPostEffectBase.h" #include "common.h" +#include "egg/gfx/eggCapTexture.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" @@ -17,18 +17,15 @@ namespace EGG { -PostEffectBase::PostEffectBase() { - field_0x00 = 0; - mpCapTexture = nullptr; - mTexMapId = GX_TEXMAP0; - mpCapTexture2 = nullptr; - mTexMapId2 = GX_TEXMAP0; - mOffsetX = 0.0f; - mOffsetY = 0.0f; - mScaleX = 1.0f; - mScaleY = 1.0f; - mRotation = 0.0f; -} +PostEffectBase::PostEffectBase() + : field_0x00(0), + mTex1((CapTextureWrapper){nullptr, GX_TEXMAP0}), + mTex2((CapTextureWrapper){nullptr, GX_TEXMAP0}), + mOffsetX(0.0f), + mOffsetY(0.0f), + mScaleX(1.0f), + mScaleY(1.0f), + mRotation(0.0f) {} void PostEffectBase::draw(f32 width, f32 height) { setMaterialInternal(); @@ -37,7 +34,7 @@ void PostEffectBase::draw(f32 width, f32 height) { } void PostEffectBase::fn_804AED20() { - draw(mpCapTexture->getWidth(), mpCapTexture->getHeight()); + draw(mTex1.mpTex->getWidth(), mTex1.mpTex->getHeight()); } void PostEffectBase::setVtxState() { @@ -55,9 +52,9 @@ void PostEffectBase::drawScreenInternal(f32 offsetX, f32 offsetY, f32 width, f32 } void PostEffectBase::loadTextureInternal() { - mpCapTexture->load(mTexMapId); - if (mpCapTexture2 != nullptr) { - mpCapTexture2->load(mTexMapId2); + mTex1.mpTex->load(mTex1.mTexMapID); + if (mTex2.mpTex != nullptr) { + mTex2.mpTex->load(mTex2.mTexMapID); } } diff --git a/src/egg/gfx/eggPostEffectBlur.cpp b/src/egg/gfx/eggPostEffectBlur.cpp index 13dfad93..d94e0692 100644 --- a/src/egg/gfx/eggPostEffectBlur.cpp +++ b/src/egg/gfx/eggPostEffectBlur.cpp @@ -4,6 +4,8 @@ #include "egg/gfx/eggCapTexture.h" #include "egg/gfx/eggDrawGX.h" #include "egg/gfx/eggGXUtility.h" +#include "egg/math/eggMath.h" +#include "egg/math/eggVector.h" #include "math.h" #include "nw4r/math/math_triangular.h" #include "nw4r/math/math_types.h" @@ -16,15 +18,12 @@ 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); - } +PostEffectBlur::PostEffectBlur() : field_0x2C(1), field_0x30(1.0f), field_0x34(1.0f) { + const GXColor clr = (GXColor){0xD7, 0xD7, 0xD7, 0xD7}; + field_0x38[0].init(clr); + field_0x38[1].init(clr); + field_0x38[2].init(clr); + field_0x38[3].init(clr); } void PostEffectBlur::draw(f32 width, f32 height) { @@ -34,12 +33,11 @@ void PostEffectBlur::draw(f32 width, f32 height) { setMatInd(); setMatPE(); setVtxState(); - f32 f1 = 1.0f / mpCapTexture->getWidth(); - f32 f2 = 1.0f / mpCapTexture->getHeight(); + f32 f1 = 1.0f / mTex1.mpTex->getWidth(); + f32 f2 = 1.0f / mTex1.mpTex->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++) { + int maxNum = (field_0x38[i].field_0x00 - 1) / 8; + for (u8 b = 0; b <= maxNum; b++) { drawInternal(i, b, f1, f2); drawScreenInternal(mOffsetX, mOffsetY, width * mScaleX, height * mScaleY); DrawGX::SetBlendMode(DrawGX::BLEND_2); @@ -50,17 +48,13 @@ void PostEffectBlur::draw(f32 width, f32 height) { void PostEffectBlur::drawInternal(u8 kernelIdx, u8 p2, f32 f1, f32 f2) { // NONMATCHING nw4r::math::MTX34 mtx; - Stage &k = field_0x38[kernelIdx]; + const Stage &k = field_0x38[kernelIdx]; - // Some regswaps and instruction swaps only at the start of the function - f32 unk_00 = k.field_0x00; + f32 f4 = k.field_0x0C * f1; + f32 f3 = k.field_0x0C * f2; + f32 rad1 = k.field_0x08 - mRotation * Math::pi(); 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; + f32 abc = (2.f * Math::pi() / k.field_0x00); u8 numTexGens = k.field_0x00 - unk_00_scale; if (numTexGens > 8) { @@ -76,12 +70,11 @@ void PostEffectBlur::drawInternal(u8 kernelIdx, u8 p2, f32 f1, f32 f2) { 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 + 1.0f, 0.0f, cos * f4, 0.0f, + 0.0f, 1.0f, sin * f3, 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++; @@ -115,7 +108,7 @@ void PostEffectBlur::drawInternal(u8 kernelIdx, u8 p2, f32 f1, f32 f2) { GXSetTevKColorSel(stage, GX_TEV_KCSEL_K0); GXSetTevKAlphaSel(stage, GX_TEV_KASEL_K0_A); - GXSetTevOrder(stage, static_cast(id), mTexMapId, GX_COLOR_NULL); + GXSetTevOrder(stage, static_cast(id), mTex1.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); diff --git a/src/egg/gfx/eggPostEffectBlurGather.cpp b/src/egg/gfx/eggPostEffectBlurGather.cpp index 0f01e6e1..0269966b 100644 --- a/src/egg/gfx/eggPostEffectBlurGather.cpp +++ b/src/egg/gfx/eggPostEffectBlurGather.cpp @@ -21,7 +21,7 @@ PostEffectBlurGather::PostEffectBlurGather() { } void PostEffectBlurGather::setMaterialInternal() { - u8 hasExtraStage = (mpCapTexture != nullptr && (field_0x2D & 1) == 0) ? 1 : 0; + u8 hasExtraStage = (mTex1.mpTex != nullptr && (field_0x2D & 1) == 0) ? 1 : 0; u8 numStages = field_0x2C + hasExtraStage * 2; setMatColorChannel(); nw4r::math::MTX34 mtx; @@ -70,7 +70,7 @@ void PostEffectBlurGather::setMaterialInternal() { 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); + GXSetTevOrder(stage, static_cast(i), mTex1.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); diff --git a/src/egg/gfx/eggPostEffectMask.cpp b/src/egg/gfx/eggPostEffectMask.cpp index 06424a66..a5819a9a 100644 --- a/src/egg/gfx/eggPostEffectMask.cpp +++ b/src/egg/gfx/eggPostEffectMask.cpp @@ -12,7 +12,7 @@ PostEffectMask::PostEffectMask() : mColor(DrawGX::WHITE), field_0x2C(0), field_0x34(0.0f), field_0x38(1.0f), field_0x1BC(1) {} void PostEffectMask::setMaterialInternal() { - bool hasTex2 = mpCapTexture2 != nullptr; + bool hasTex2 = mTex2.mpTex != nullptr; loadTextureInternal(); GXColor resColor; scaleColor(resColor, mColor, false, field_0x34); @@ -30,7 +30,7 @@ void PostEffectMask::setMaterialInternal() { GXTevScale scale = field_0x2C == 0 ? GetTevScale() : GX_CS_SCALE_1; GXColor c = resColor; - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, mTexMapId, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, mTex1.mTexMapID, GX_COLOR_NULL); GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); GXSetTevKColor(GX_KCOLOR0, c); @@ -43,7 +43,7 @@ void PostEffectMask::setMaterialInternal() { case 0: { if (hasTex2) { GXSetNumTevStages(2); - GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, mTexMapId2, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, mTex2.mTexMapID, GX_COLOR_NULL); GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); @@ -59,12 +59,12 @@ void PostEffectMask::setMaterialInternal() { if (hasTex2) { GXSetNumTevStages(3); scale = GetTevScale(); - GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, mTexMapId, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, mTex1.mTexMapID, GX_COLOR_NULL); GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXA, GX_CC_ZERO); GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, scale, 1, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); - GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD1, mTexMapId2, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD1, mTex2.mTexMapID, GX_COLOR_NULL); GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); @@ -73,7 +73,7 @@ void PostEffectMask::setMaterialInternal() { } else { GXSetNumTevStages(2); scale = GetTevScale(); - GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, mTexMapId, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, mTex1.mTexMapID, GX_COLOR_NULL); GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXA, GX_CC_ZERO); GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, scale, 1, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); diff --git a/src/egg/gfx/eggPostEffectMaskDOF.cpp b/src/egg/gfx/eggPostEffectMaskDOF.cpp index 9bd54d28..7e9bc43a 100644 --- a/src/egg/gfx/eggPostEffectMaskDOF.cpp +++ b/src/egg/gfx/eggPostEffectMaskDOF.cpp @@ -1,3 +1,196 @@ #include "egg/gfx/eggPostEffectMaskDOF.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggCpuTexture.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +namespace EGG { + +static const GXColor sColorNear = (GXColor){0x00, 0xFF, 0x00, 0xFF}; +static const GXColor sColorFar = (GXColor){0xFF, 0x00, 0x00, 0x00}; +static const GXColor sColorCenter = (GXColor){0x00, 0x00, 0x00, 0x00}; + +PostEffectMaskDOF::PostEffectMaskDOF() + : field_0x2C(8), + field_0x44(0.5), + field_0x48(0.f), + field_0x4C(1.f), + field_0x50(0.f, 0.f), + mCpuTexArrIdx(2), + field_0x60(2) { + for (int i = 0; i < 3; i++) { + mpCpuTexArr[i] = new CpuTexture(64, 2, GX_TF_RGBA8); + mpCpuTexArr[i]->configure(); + mpCpuTexArr[i]->allocate(nullptr); + mpCpuTexArr[i]->setWrapS(GX_CLAMP); + mpCpuTexArr[i]->setWrapT(GX_CLAMP); + } + + mpCpuTex = new CpuTexture(64, 64, GX_TF_RGBA8); + mpCpuTex->configure(); + mpCpuTex->allocate(nullptr); + mpCpuTex->setWrapS(GX_CLAMP); + mpCpuTex->setWrapT(GX_CLAMP); + setUpGradation(); + field_0x00 = 0; +} + +void PostEffectMaskDOF::setUpGradation() {} + +void PostEffectMaskDOF::draw(f32 width, f32 height) { + setMaterialInternal(); + setVtxState(); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_TEX_ST, GX_F32, 0); + GXSetVtxDesc(GX_VA_TEX1, GX_DIRECT); + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, width * mScaleX, height * mScaleY, 1.f); + PSMTXTransApply(mtx, mtx, mOffsetX, mOffsetY, 0.f); + GXLoadPosMtxImm(mtx, GX_PNMTX0); + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition2u8(0, 0); + GXPosition2f32(field_0x50.x, field_0x50.y); + GXPosition2u8(1, 1); + GXPosition2f32(field_0x50.x, field_0x50.y); + GXPosition2u8(2, 2); + GXPosition2f32(field_0x50.x, field_0x50.y); + GXPosition2u8(3, 3); + GXPosition2f32(field_0x50.x, field_0x50.y); + GXSetTexCoordScaleManually(GX_TEXCOORD1, 0, 0x40, 0); + GXSetTexCoordBias(GX_TEXCOORD1, 0, 0); +} + +void PostEffectMaskDOF::setMaterialInternal() { + loadTextureInternal(); + setMatColorChannel(); + GXSetNumTexGens(2); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0, false, GX_DUALMTX_IDENT); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_TEXMTX_IDENT, false, GX_DUALMTX_IDENT); + nw4r::math::MTX34 baseTexMtx; + getBaseTexMtx(&baseTexMtx); + GXLoadTexMtxImm(baseTexMtx, GX_TEXMTX0, GX_MTX_2x4); + GXSetNumIndStages(1); + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, mTex1.mTexMapID); + GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); + + CpuTexture *pCpuTex = mpCpuTexArr[mCpuTexArrIdx]; + switch (field_0x60) { + case 0: { + GXSetNumTevStages(1); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD1, GX_TEXMAP2, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + 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_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_OFF, GX_ITW_OFF, false, false, + GX_ITBA_OFF + ); + + s8 scaleExp = 0; + f32 fVar2 = scaleExp + 1; + f32 fVar3 = 1.f / (field_0x4C - field_0x48); + + f32 fVar1 = fVar3 / fVar2; + + while (fVar1 > (1023.f / 1024.f)) { + fVar1 /= 2.f; + fVar2 *= 2.f; + + scaleExp++; + } + while (0.f < fVar1 && fVar1 < 0.5f) { + fVar1 *= 2.f; + fVar2 /= 2.f; + + scaleExp--; + } + f32 indTexMtx[2][3] = { + {fVar1 / 256.f, fVar1, 0.f}, + { 0.f, 0.f, 0.f} + }; + GXSetIndTexMtx(GX_ITM_0, indTexMtx, scaleExp - 2); + field_0x50.x = -(field_0x44 * fVar1 * fVar2) + 0.5f; + if (field_0x2C & 8) { + field_0x50.x = (s32)(field_0x50.x * 128.f) / 128.f; + } + field_0x50.y = 0.f; + GXSetTexCoordScaleManually(GX_TEXCOORD1, true, 0x40, 0); + GXSetTexCoordBias(GX_TEXCOORD1, 0, 0); + } break; + case 1: { + pCpuTex = mpCpuTex; + GXSetNumTevStages(2); + 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_TEXMAP2, GX_COLOR_NULL); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP2, 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_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, true, false, + GX_ITBA_OFF + ); + field_0x50.y = field_0x4C; + + f32 val = 1023.f / 1024.f; + f32 indTexMtx[2][3] = { + {val / 256.f, val, 0.f}, + { 0.f, 0.f, 0.f} + }; + + GXSetIndTexMtx(GX_ITM_0, indTexMtx, 8); + + int unk = 1024; + field_0x50.x = -field_0x44 + 0.5f / unk; + + GXSetTexCoordScaleManually(GX_TEXCOORD1, GX_TEXCOORD1, 0, 0x40); + GXSetTexCoordBias(GX_TEXCOORD1, 0, 0); + } break; + case 2: { + GXSetNumTevStages(1); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP2, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + 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_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, false, false, + GX_ITBA_OFF + ); + + f32 indTexMtx[2][3] = { + {0.f, 0.5f, 0.f}, + {0.f, 0.f, 0.f} + }; + GXSetIndTexMtx(GX_ITM_0, indTexMtx, -1); + + field_0x50.y = 0.f; + field_0x50.x = 0.f; + } break; + } + pCpuTex->load(GX_TEXMAP2); + setMatPE(); +} + +const GXColor &PostEffectMaskDOF::getNearColor() { + return sColorNear; +} +const GXColor &PostEffectMaskDOF::getFarColor() { + return sColorFar; +} +const GXColor &PostEffectMaskDOF::getCenterColor() { + return sColorCenter; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggPostEffectSimple.cpp b/src/egg/gfx/eggPostEffectSimple.cpp index 24c18b9f..c6525a9a 100644 --- a/src/egg/gfx/eggPostEffectSimple.cpp +++ b/src/egg/gfx/eggPostEffectSimple.cpp @@ -29,7 +29,7 @@ void PostEffectSimple::setMaterialInternal() { GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); GXSetTevKColor(GX_KCOLOR0, c); - GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, mTexMapId, GX_COLOR_NULL); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, mTex1.mTexMapID, GX_COLOR_NULL); GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, field_0x34, 1, GX_TEVPREV); switch (field_0x38) { diff --git a/src/egg/gfx/eggPostEffectUnk2.cpp b/src/egg/gfx/eggPostEffectUnk2.cpp index abf57b73..ffa43714 100644 --- a/src/egg/gfx/eggPostEffectUnk2.cpp +++ b/src/egg/gfx/eggPostEffectUnk2.cpp @@ -74,8 +74,8 @@ void PostEffectUnk2::draw(f32 width, f32 height) { {-1.0f, 1.0f}, }; - const f32 s1 = field_0x40 / mpCapTexture->getWidth(); - const f32 s2 = field_0x40 / mpCapTexture->getHeight(); + const f32 s1 = field_0x40 / mTex1.mpTex->getWidth(); + const f32 s2 = field_0x40 / mTex1.mpTex->getHeight(); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { f32 mtx[2][4]; @@ -120,9 +120,9 @@ void PostEffectUnk2::setMaterialInternal() { 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); + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, mTex1.mTexMapID); + GXSetIndTexOrder(GX_INDTEXSTAGE1, GX_TEXCOORD2, mTex1.mTexMapID); + GXSetIndTexOrder(GX_INDTEXSTAGE2, GX_TEXCOORD3, mTex1.mTexMapID); setMatPE(); mpTexture->load(GX_TEXMAP1); From 178af0c42b1fcd9eb7cfd1527fbc1d773998009f Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 23 Mar 2025 22:51:40 +0100 Subject: [PATCH 36/62] LightManager halfway there --- config/SOUE01/symbols.txt | 6 +- include/egg/gfx/eggG3DUtility.h | 2 + include/egg/gfx/eggLightManager.h | 61 ++++- include/egg/gfx/eggLightObject.h | 48 +++- include/egg/gfx/eggLightTextureMgr.h | 1 + include/nw4r/g3d/g3d_calcworld.h | 4 +- include/nw4r/g3d/g3d_obj.h | 2 +- include/nw4r/g3d/res/g3d_resanmamblight.h | 10 + include/nw4r/g3d/res/g3d_resanmscn.h | 16 ++ include/nw4r/g3d/res/g3d_reslightset.h | 4 + include/nw4r/g3d/res/g3d_resmat.h | 2 +- src/egg/gfx/eggLightManager.cpp | 282 ++++++++++++++++++++-- src/egg/gfx/eggLightObject.cpp | 6 +- 13 files changed, 398 insertions(+), 46 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index cd6d5f2a..7c6c0861 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26563,7 +26563,7 @@ GetOrthographicParam___Q23EGG7FrustumCFPfPfPfPf = .text:0x804A66C0; // type:func __sinit_\eggFrustum_cpp = .text:0x804A6830; // type:function size:0x24 scope:local FUN_804a6860 = .text:0x804A6860; // type:function size:0x104 FUN_804a6970 = .text:0x804A6970; // type:function size:0x34 -FUN_804a69b0 = .text:0x804A69B0; // type:function size:0x1E8 +setUpLightSet__Q23EGG10G3DUtilityFRQ34nw4r3g3d12LightSettingQ34nw4r3g3d9ResAnmScni = .text:0x804A69B0; // type:function size:0x1E8 FUN_804a6ba0 = .text:0x804A6BA0; // type:function size:0x104 FUN_804a6cb0 = .text:0x804A6CB0; // type:function size:0x104 FUN_804a6dc0 = .text:0x804A6DC0; // type:function size:0x144 @@ -26594,7 +26594,7 @@ __dt__Q23EGG12LightManagerFv = .text:0x804A81E0; // type:function size:0xA0 Reset__Q23EGG12LightManagerFv = .text:0x804A8280; // type:function size:0x12C Calc__Q23EGG12LightManagerFPQ34nw4r3g3d7ScnRoot = .text:0x804A83B0; // type:function size:0xC8 CalcView__Q23EGG12LightManagerFRCQ34nw4r4math5MTX34UcPQ34nw4r3g3d7ScnRoot = .text:0x804A8480; // type:function size:0x118 -EGG__LightManager__LoadLightSet = .text:0x804A85A0; // type:function size:0x6C +LoadLightSet__Q23EGG12LightManagerFiPUlPUlPUlPUlP8_GXColor = .text:0x804A85A0; // type:function size:0x6C DoneDraw__Q23EGG12LightManagerFv = .text:0x804A8610; // type:function size:0x30 LoadScnLightInner__Q23EGG12LightManagerFQ34nw4r3g3d9ResAnmScnfsUl = .text:0x804A8640; // type:function size:0x280 CopyToG3D_Ambient__Q23EGG12LightManagerCFPQ34nw4r3g3d7ScnRoot = .text:0x804A88C0; // type:function size:0x3C @@ -26616,7 +26616,7 @@ __ct__Q23EGG11LightObjectFv = .text:0x804A9830; // type:function size:0xB8 Reset__Q23EGG11LightObjectFv = .text:0x804A98F0; // type:function size:0x110 Calc__Q23EGG11LightObjectFv = .text:0x804A9A00; // type:function size:0x3C CalcView__Q23EGG11LightObjectFRCQ34nw4r4math5MTX34 = .text:0x804A9A40; // type:function size:0x1E8 -FUN_804a9c30 = .text:0x804A9C30; // type:function size:0x104 +fn_804A9C30__Q23EGG11LightObjectCFPCQ23EGG12LightTexturePQ34nw4r4math4VEC3P8_GXColor = .text:0x804A9C30; // type:function size:0x104 InitGX__Q23EGG11LightObjectCFP11_GXLightObj = .text:0x804A9D40; // type:function size:0x200 CopyToG3D_World__Q23EGG11LightObjectCFRQ34nw4r3g3d8LightObj = .text:0x804A9F40; // type:function size:0x150 CopyToG3D_View__Q23EGG11LightObjectCFRQ34nw4r3g3d8LightObjRCQ34nw4r4math5MTX34 = .text:0x804AA090; // type:function size:0x144 diff --git a/include/egg/gfx/eggG3DUtility.h b/include/egg/gfx/eggG3DUtility.h index cc1c9175..bb26c177 100644 --- a/include/egg/gfx/eggG3DUtility.h +++ b/include/egg/gfx/eggG3DUtility.h @@ -18,6 +18,8 @@ public: void *param_6, int param_7, int param_8 ); + static void setUpLightSet(nw4r::g3d::LightSetting&, nw4r::g3d::ResAnmScn, int); + private: static MEMAllocator *sAllocator; }; diff --git a/include/egg/gfx/eggLightManager.h b/include/egg/gfx/eggLightManager.h index d1ed1cb8..c715dcef 100644 --- a/include/egg/gfx/eggLightManager.h +++ b/include/egg/gfx/eggLightManager.h @@ -4,6 +4,9 @@ #include "egg/egg_types.h" #include "egg/gfx/eggLightObject.h" #include "egg/prim/eggBinary.h" +#include "nw4r/g3d/g3d_light.h" +#include "nw4r/g3d/res/g3d_resanmamblight.h" +#include "nw4r/g3d/res/g3d_resanmscn.h" #include "nw4r/types_nw4r.h" #include "rvl/GX/GXLight.h" #include "rvl/GX/GXTypes.h" @@ -20,18 +23,36 @@ class LightManager : public IBinary { union Counts { struct { /* 0x00 */ u8 mNumEggLightObjects; - /* 0x01 */ u8 mNumUnks; + /* 0x01 */ u8 mNumAmbientObjects; }; }; - struct Unk1 { - /* 0x00 */ GXColor mColor; - /* 0x04 */ const char *mStr; + struct AmbientObject { + /* 0x00 */ nw4r::g3d::AmbLightObj mLightObj; + /* 0x04 */ const char *mLightName; /* 0x08 */ u8 field_0x08; }; public: - struct BinData {}; + struct BinAmbient { + /* 0x00 */ u8 field_0x00; + /* 0x01 */ u8 field_0x01; + /* 0x02 */ u8 field_0x02; + /* 0x03 */ u8 field_0x03; + /* 0x04 */ u8 field_0x04; + /* 0x05 */ u8 field_0x05; + /* 0x06 */ u8 field_0x06; + /* 0x07 */ u8 field_0x07; + }; + + struct BinData { + /* 0x00 */ u16 mNumLightObjects; + /* 0x02 */ u16 mNumAmbientObjects; + /* 0x04 */ GXColor mColor; + /* 0x08 */ u8 _0x08[0x18 - 0x08]; + /* 0x18 */ LightObject::Bin mObjData[1]; + }; + // vt at 0x00 LightManager(u32, u32, u8); virtual ~LightManager(); @@ -44,28 +65,46 @@ public: virtual void CalcView(const nw4r::math::MTX34 &, u8, nw4r::g3d::ScnRoot *); virtual void DoneDraw(); + void LoadLightSet(int, u32 *, u32 *, u32 *, u32 *, GXColor *); + + void LoadScnLightInner(nw4r::g3d::ResAnmScn, f32, s16, u32); + + void AnmScnRes_GetAmbLightColor(AmbientObject *, nw4r::g3d::ResAnmAmbLight, f32) const; + + void CopyToG3D_Ambient(nw4r::g3d::ScnRoot *) const; + void CopyToG3D_World(nw4r::g3d::ScnRoot *) const; + void CopyToG3D_View(nw4r::g3d::ScnRoot *, const nw4r::math::MTX34 &) const; + void BecomeInvalidLight(int); LightTextureManager *GetTextureMgr() const { return mpTextureMgr; } + static u16 CheckedNumLightObjs(u8 num) { + return num < 8 ? num : 8; + } + + const LightObject *GetLightObject(int i) const { + return &mpLightData[i].mLightObject; + } + LightObject *GetLightObject(int i) { return &mpLightData[i].mLightObject; } - /* 0x04 */ Counts mCounts0x04; - /* 0x06 */ Counts mCounts0x06; + /* 0x04 */ Counts mCounts; + /* 0x06 */ Counts mSavedCounts; /* 0x08 */ LightData *mpLightData; - /* 0x0C */ Unk1 *mpUnk1; + /* 0x0C */ AmbientObject *mpAmbientObjects; /* 0x10 */ GXLightObj *mpLightObjs; /* 0x14 */ LightTextureManager *mpTextureMgr; /* 0x18 */ GXColor mColor; - /* 0x1C */ u8 field_0x1C; + /* 0x1C */ u8 mNumGxObjsPerEggObj; /* 0x1D */ u8 field_0x1D; /* 0x1E */ u16 mFlags; - /* 0x20 */ u32 field_0x20; - /* 0x24 */ s16 field_0x24; + /* 0x20 */ nw4r::g3d::ResAnmScn mResAnmScn; + /* 0x24 */ s16 mRefNumber; }; } // namespace EGG diff --git a/include/egg/gfx/eggLightObject.h b/include/egg/gfx/eggLightObject.h index ac7f8ceb..afef331c 100644 --- a/include/egg/gfx/eggLightObject.h +++ b/include/egg/gfx/eggLightObject.h @@ -7,12 +7,32 @@ #include "nw4r/math/math_types.h" #include "rvl/GX/GXLight.h" #include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" namespace EGG { class LightObject : public IBinary { public: - struct BinData {}; + struct BinData { + /* 0x00 */ u8 mSpotFn; + /* 0x01 */ u8 mDistAttnFn; + /* 0x02 */ u8 field_0x02; + /* 0x03 */ u8 field_0x03; + /* 0x04 */ u16 mIndex; + /* 0x06 */ u16 mFlags; + /* 0x08 */ Vec mPos; + /* 0x14 */ Vec mAt; + /* 0x20 */ f32 field_0x20; + /* 0x24 */ GXColor mWhite; + /* 0x28 */ GXColor mBlack; + /* 0x2C */ f32 field_0x2C; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ f32 field_0x34; + /* 0x38 */ f32 field_0x38; + /* 0x3C */ u16 field_0x3C; + /* 0x3E */ u16 field_0x3E; + }; + LightObject(); virtual ~LightObject() {} @@ -66,10 +86,34 @@ public: field_0xA0 = 0; } - void ClearFlag4() { + void ClearFlag2() { mFlags = mFlags & 0xFFFE; } + bool CheckFlag1() const { + return (mFlags & 1) != 0; + } + + void SetOtherFlag1() { + field_0xA0 |= 1; + } + + void ClearOtherFlag1() { + field_0xA0 = field_0xA0 & ~1; + } + + bool CheckFlag2() const { + return (mFlags & 2) != 0; + } + + u16 GetField0x06() const { + return field_0x06; + } + + void UpdatePosAt(LightObject &other) { + SetPosAt(other.mPos, other.mAt); + } + private: /* 0x04 */ u16 mIndex; /* 0x06 */ u16 field_0x06; diff --git a/include/egg/gfx/eggLightTextureMgr.h b/include/egg/gfx/eggLightTextureMgr.h index 18e0cc8b..4225e0db 100644 --- a/include/egg/gfx/eggLightTextureMgr.h +++ b/include/egg/gfx/eggLightTextureMgr.h @@ -30,6 +30,7 @@ public: int replaceModelTextures(nw4r::g3d::ResMdl) const; int replaceModelTexture(u16, nw4r::g3d::ResMdl) const; void drawAndCaptureTexture(f32, f32, f32, f32); + void frameReset(); // Inofficial static const void *getLtexFromLmap(const void *lmap, u16 index); diff --git a/include/nw4r/g3d/g3d_calcworld.h b/include/nw4r/g3d/g3d_calcworld.h index 989886eb..d32c5adf 100644 --- a/include/nw4r/g3d/g3d_calcworld.h +++ b/include/nw4r/g3d/g3d_calcworld.h @@ -63,13 +63,13 @@ public: void SetScale(f32 x, f32 y, f32 z); void GetMtx(nw4r::math::MTX34 *out) { - if (out != nullptr) { + if (out != NULL) { PSMTXCopy(*mpM, *out); } } void SetMtx(const nw4r::math::MTX34 *arg) { - if (arg != nullptr) { + if (arg != NULL) { PSMTXCopy(*arg, *mpM); } else { PSMTXIdentity(*mpM); diff --git a/include/nw4r/g3d/g3d_obj.h b/include/nw4r/g3d/g3d_obj.h index 07b7ebcf..769f0251 100644 --- a/include/nw4r/g3d/g3d_obj.h +++ b/include/nw4r/g3d/g3d_obj.h @@ -133,7 +133,7 @@ public: if (pObj != NULL && pObj->IsDerivedFrom(TTo::GetTypeObjStatic())) { return static_cast(pObj); } - return nullptr; + return NULL; } private: diff --git a/include/nw4r/g3d/res/g3d_resanmamblight.h b/include/nw4r/g3d/res/g3d_resanmamblight.h index c9e2a48c..cbd5a28e 100644 --- a/include/nw4r/g3d/res/g3d_resanmamblight.h +++ b/include/nw4r/g3d/res/g3d_resanmamblight.h @@ -58,6 +58,16 @@ public: u32 GetRefNumber() const { return ref().refNumber; } + + const char *GetName() const { + const ResAnmAmbLightData &r = ref(); + + if (r.name != 0) { + return NW4R_G3D_OFS_TO_RESNAME(&r, r.name).GetName(); + } + + return NULL; + } }; } // namespace g3d diff --git a/include/nw4r/g3d/res/g3d_resanmscn.h b/include/nw4r/g3d/res/g3d_resanmscn.h index 57540436..c2f270aa 100644 --- a/include/nw4r/g3d/res/g3d_resanmscn.h +++ b/include/nw4r/g3d/res/g3d_resanmscn.h @@ -98,6 +98,22 @@ public: u16 GetResAnmFogMaxRefNumber() const { return ref().info.numResAnmFogData; } + + u16 GetResAnmLightMaxRefNumber() const { + return ref().info.numResAnmLightData; + } + + u16 GetResAnmAmbLightMaxRefNumber() const { + return ref().info.numResAnmAmbLightData; + } + + u16 GetResLightSetMaxRefNumber() const { + return ref().info.numResLightSetData; + } + + u16 GetSpecularLightNumber() const { + return ref().info.numSpecularLight; + } }; } // namespace g3d diff --git a/include/nw4r/g3d/res/g3d_reslightset.h b/include/nw4r/g3d/res/g3d_reslightset.h index 3669d25c..23e0429f 100644 --- a/include/nw4r/g3d/res/g3d_reslightset.h +++ b/include/nw4r/g3d/res/g3d_reslightset.h @@ -49,6 +49,10 @@ public: return ref().ambLightId; } + u32 GetLightID(u32 index) const { + return ref().lightId[index]; + } + u32 GetNumLight() const { return ref().numLight; } diff --git a/include/nw4r/g3d/res/g3d_resmat.h b/include/nw4r/g3d/res/g3d_resmat.h index 0397d13e..9a110ba5 100644 --- a/include/nw4r/g3d/res/g3d_resmat.h +++ b/include/nw4r/g3d/res/g3d_resmat.h @@ -501,7 +501,7 @@ public: return NW4R_G3D_OFS_TO_RESNAME(&r, r.nameTex).GetName(); } - return nullptr; + return NULL; } bool IsCIFmt() const { diff --git a/src/egg/gfx/eggLightManager.cpp b/src/egg/gfx/eggLightManager.cpp index ba8666b5..3e63eb82 100644 --- a/src/egg/gfx/eggLightManager.cpp +++ b/src/egg/gfx/eggLightManager.cpp @@ -3,42 +3,52 @@ #include "common.h" #include "egg/egg_types.h" #include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggG3DUtility.h" #include "egg/gfx/eggLightObject.h" #include "egg/gfx/eggLightTextureMgr.h" +#include "nw4r/g3d/g3d_light.h" +#include "nw4r/g3d/g3d_scnroot.h" +#include "nw4r/g3d/g3d_state.h" +#include "nw4r/g3d/res/g3d_resanmamblight.h" +#include "nw4r/g3d/res/g3d_resanmscn.h" +#include "nw4r/g3d/res/g3d_reslightset.h" +#include "nw4r/math/math_types.h" #include "rvl/GX/GXLight.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" +#include "rvl/OS/OSCache.h" namespace EGG { -LightManager::LightManager(u32 p1, u32 p2, u8 p3) { +LightManager::LightManager(u32 numEggObjects, u32 numAmbientObject, u8 numGxObjsPerEggObj) { Counts c; - c.mNumEggLightObjects = p1; - c.mNumUnks = p2; + c.mNumEggLightObjects = numEggObjects; + c.mNumAmbientObjects = numAmbientObject; - mCounts0x04 = c; - mCounts0x06 = c; + mCounts = c; + mSavedCounts = c; mpLightData = nullptr; - mpUnk1 = nullptr; + mpAmbientObjects = nullptr; mpTextureMgr = nullptr; - field_0x1C = p3; + mNumGxObjsPerEggObj = numGxObjsPerEggObj; mFlags = 0x40; - field_0x20 = 0; - field_0x24 = -1; + mResAnmScn = nw4r::g3d::ResAnmScn(nullptr); + mRefNumber = -1; mpTextureMgr = new LightTextureManager(this); - u16 numGxObjs = mCounts0x04.mNumEggLightObjects < 8 ? mCounts0x04.mNumEggLightObjects : 8; - mpLightObjs = new GXLightObj[field_0x1C * numGxObjs](); - mpLightData = new LightData[mCounts0x04.mNumEggLightObjects](); - mpUnk1 = new Unk1[mCounts0x04.mNumUnks](); + mpLightObjs = new GXLightObj[mNumGxObjsPerEggObj * CheckedNumLightObjs(mCounts.mNumEggLightObjects)](); + mpLightData = new LightData[mCounts.mNumEggLightObjects](); + mpAmbientObjects = new AmbientObject[mCounts.mNumAmbientObjects](); - for (int i = 0; i < mCounts0x04.mNumEggLightObjects; i++) { + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { GetLightObject(i)->SetIndex(i); GetLightObject(i)->ClearField0xA0(); BecomeInvalidLight(i); } - for (u16 i = 0; i < (u32)mCounts0x04.mNumUnks; i++) { - mpUnk1[i].field_0x08 = 0; + for (u16 i = 0; i < (u32)mCounts.mNumAmbientObjects; i++) { + mpAmbientObjects[i].field_0x08 = 0; } Reset(); @@ -48,27 +58,253 @@ LightManager::~LightManager() { delete mpTextureMgr; delete[] mpLightObjs; delete[] mpLightData; - delete[] mpUnk1; + delete[] mpAmbientObjects; } -static const char *resetPattern = "--"; +static const char *ambientLightPlaceholderName = "--"; void LightManager::Reset() { - for (int i = 0; i < mCounts0x04.mNumEggLightObjects; i++) { + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { LightObject *obj = GetLightObject(i); obj->Reset(); if (i > 0) { - obj->ClearFlag4(); + obj->ClearFlag2(); } } - for (u16 i = 0; i < (u32)mCounts0x04.mNumUnks; i++) { - mpUnk1[i].mColor = (GXColor){0x64, 0x64, 0x64, 0xFF}; - mpUnk1[i].mStr = resetPattern; + for (u16 i = 0; i < (u32)mCounts.mNumAmbientObjects; i++) { + mpAmbientObjects[i].mLightObj = (nw4r::g3d::AmbLightObj){0x64, 0x64, 0x64, 0xFF}; + mpAmbientObjects[i].mLightName = ambientLightPlaceholderName; } mColor = DrawGX::BLACK; field_0x1D = 0; mFlags = mFlags & 0xFFE0; } +void LightManager::Calc(nw4r::g3d::ScnRoot *root) { + if ((mFlags & 4) == 0) { + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + LightObject *obj = GetLightObject(i); + if (obj->CheckFlag2()) { + u16 u = obj->GetField0x06(); + if (i != u) { + obj->UpdatePosAt(*GetLightObject(u)); + } + } + obj->Calc(); + } + mFlags |= 4; + mpTextureMgr->frameReset(); + } + + if (root != nullptr) { + CopyToG3D_World(root); + } +} + +void LightManager::CalcView(const nw4r::math::MTX34 &viewMtx, u8 lightObjOffset, nw4r::g3d::ScnRoot *root) { + // NONMATCHING - regswaps + field_0x1D = lightObjOffset; + mFlags |= 8; + + GXLightObj *gxObj = mpLightObjs + lightObjOffset * CheckedNumLightObjs(mCounts.mNumEggLightObjects); + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + GetLightObject(i)->CalcView(viewMtx); + if (i < CheckedNumLightObjs(mCounts.mNumEggLightObjects)) { + GetLightObject(i)->InitGX(&gxObj[i]); + } + } + DCFlushRange(gxObj, CheckedNumLightObjs(mCounts.mNumEggLightObjects) * sizeof(GXLightObj)); + if (root != nullptr) { + nw4r::math::MTX34 tmp; + PSMTXInverse(viewMtx, tmp); + CopyToG3D_View(root, tmp); + } +} + +void LightManager::LoadLightSet( + int id, u32 *pDiffColorMask, u32 *pDiffAlphaMask, u32 *pSpecColorMask, u32 *pSpecAlphaMask, GXColor *pColor +) { + nw4r::g3d::AmbLightObj o; + nw4r::g3d::G3DState::LoadLightSet(id, pDiffColorMask, pDiffAlphaMask, pSpecColorMask, pSpecAlphaMask, &o); + if (pColor != nullptr) { + pColor->r = o.r; + pColor->g = o.g; + pColor->b = o.b; + pColor->a = o.a; + } +} + +void LightManager::DoneDraw() { + if (((mFlags & 8) != 0) && ((mFlags & 4) != 0)) { + mFlags = mFlags & 0xffef; + } + mFlags = mFlags & 0xfffb; + mFlags = mFlags & 0xfff7; +} + +void LightManager::LoadScnLightInner(nw4r::g3d::ResAnmScn scn, f32 frame, s16 refNumber, u32 u2) { + // NONMATCHING - small problems around lightSet.GetLightID + if (!scn.IsValid()) { + return; + } + + if ((u2 & 2) != 0) { + mFlags |= 0x10; + mResAnmScn = scn; + mRefNumber = refNumber; + } + + if ((u2 & 1) == 0) { + return; + } + + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + BecomeInvalidLight(i); + } + + nw4r::g3d::ResLightSet lightSet = scn.GetResLightSetByRefNumber(refNumber); + s32 lightId = -1; + if (lightSet.IsValid()) { + lightId = lightSet.GetAmbLightID(); + } + u32 loopMax = mCounts.mNumAmbientObjects; + if (scn.GetResAnmAmbLightMaxRefNumber() < loopMax) { + loopMax = scn.GetResAnmAmbLightMaxRefNumber(); + } + for (u32 i = 0; i < loopMax; i++) { + AmbientObject *ambient = &mpAmbientObjects[i]; + ambient->field_0x08 = ambient->field_0x08 & 0xFE; + if (lightId == -1 || i == lightId) { + nw4r::g3d::ResAnmAmbLight light = scn.GetResAnmAmbLightByRefNumber(i); + AnmScnRes_GetAmbLightColor(ambient, light, frame); + ambient->field_0x08 |= 1; + } + } + + u32 numObjs = mCounts.mNumEggLightObjects; + u32 numAmb = scn.GetResAnmLightMaxRefNumber(); + u32 numTotal = numAmb + scn.GetSpecularLightNumber(); + u32 numLight = numAmb <= numObjs ? numAmb : numObjs; + u32 maxIdx = numTotal <= numObjs ? numTotal : numObjs; + + if (lightSet.IsValid()) { + numLight = lightSet.GetNumLight(); + } + + for (u32 i = 0; i < numLight; i++) { + u32 idx = lightSet.IsValid() ? lightSet.GetLightID(i) : i; + GetLightObject(idx)->ClearFlag2(); + } + + for (u32 i = 0; i < numLight; i++) { + u32 idx = lightSet.IsValid() ? lightSet.GetLightID(i) : i; + nw4r::g3d::ResAnmLight light = scn.GetResAnmLightByRefNumber(idx); + if (light.IsValid()) { + LightObject *obj = nullptr; + LightData *dat = &mpLightData[idx]; + if (!GetLightObject(idx)->CheckFlag1()) { + if (light.HasSpecularLight() && light.GetSpecularLightIdx() < maxIdx) { + obj = GetLightObject(light.GetSpecularLightIdx()); + } + dat->mLightObject.CopyFromG3D(light, frame, obj, false); + mpLightData[idx].mLightObject.SetOtherFlag1(); + } + } + } +} + +void LightManager::CopyToG3D_Ambient(nw4r::g3d::ScnRoot *root) const { + // NONMATCHING - word copy + nw4r::g3d::LightSetting &setting = root->GetLightSetting(); + for (int i = 0; i < mCounts.mNumAmbientObjects; i++) { + setting.GetAmbLightObjArray()[i] = mpAmbientObjects[i].mLightObj; + } +} + +void LightManager::CopyToG3D_World(nw4r::g3d::ScnRoot *root) const { + // NONMATCHING - loop registers, variables + nw4r::g3d::LightSetting &setting = root->GetLightSetting(); + if ((mFlags & 0x10) != 0) { + G3DUtility::setUpLightSet(setting, mResAnmScn, mRefNumber); + } + CopyToG3D_Ambient(root); + for (int i = 0; i < mCounts.mNumAmbientObjects; i++) { + GetLightObject(i)->CopyToG3D_World(setting.GetLightObjArray()[i]); + } +} + +void LightManager::CopyToG3D_View(nw4r::g3d::ScnRoot *root, const nw4r::math::MTX34 &viewMtx) const { + nw4r::g3d::LightSetting &setting = root->GetLightSetting(); + // NONMATCHING - loop registers, variables + for (int i = 0; i < mCounts.mNumEggLightObjects; i++) { + GetLightObject(i)->CopyToG3D_View(setting.GetLightObjArray()[i], viewMtx); + } +} + +void LightManager::AnmScnRes_GetAmbLightColor( + EGG::LightManager::AmbientObject *obj, nw4r::g3d::ResAnmAmbLight light, f32 frame +) const { + nw4r::g3d::AmbLightAnmResult res; + if (!light.IsValid()) { + res.flags = 0; + res.color = -1; + } else { + light.GetAnmResult(&res, frame); + obj->mLightName = light.GetName(); + } + + if ((res.flags & nw4r::g3d::AmbLightAnmResult::FLAG_COLOR_ENABLE) == 0) { + res.color |= 0xFFFFFF00; + } + + if ((res.flags & nw4r::g3d::AmbLightAnmResult::FLAG_ALPHA_ENABLE) == 0) { + res.color |= 0x000000FF; + } + + u32 color = res.color; + + obj->mLightObj.r = (color >> 24) & 0xFF; + obj->mLightObj.g = (color >> 16) & 0xFF; + obj->mLightObj.b = (color >> 8) & 0xFF; + obj->mLightObj.a = (color >> 0) & 0xFF; +} + +void LightManager::GetBinaryInner(Bin *bin) const { + // NONMATCHING - regswaps, loop increments + u16 numObjs = mSavedCounts.mNumEggLightObjects; + u16 numAmbient = mSavedCounts.mNumAmbientObjects; + bin->mData.mNumLightObjects = numObjs; + bin->mData.mNumAmbientObjects = mSavedCounts.mNumAmbientObjects; + + LightObject::Bin *pObj = reinterpret_cast(&bin->mData.mObjData); + for (int i = 0; i < numObjs; i++) { + GetLightObject(i)->GetBinary(&pObj[i]); + } + + BinAmbient *pAmp = reinterpret_cast(&pObj[numObjs]); + for (u16 i = 0; i < numAmbient; i++) { + AmbientObject &o = mpAmbientObjects[i]; + pAmp[i].field_0x00 = o.mLightObj.r; + pAmp[i].field_0x01 = o.mLightObj.g; + pAmp[i].field_0x02 = o.mLightObj.b; + pAmp[i].field_0x03 = o.mLightObj.a; + pAmp[i].field_0x07 = 0; + pAmp[i].field_0x06 = 0; + pAmp[i].field_0x05 = 0; + pAmp[i].field_0x04 = 0; + } + + bin->mData.mColor = mColor; +} + +void LightManager::BecomeInvalidLight(int idx) { + mpLightData[idx].mLightObject.ClearOtherFlag1(); +} + +size_t LightManager::GetBinarySize() const { + return sizeof(Bin) + sizeof(LightObject::Bin) * (mSavedCounts.mNumEggLightObjects - 1) + + sizeof(BinAmbient) * mSavedCounts.mNumAmbientObjects; +} + } // namespace EGG diff --git a/src/egg/gfx/eggLightObject.cpp b/src/egg/gfx/eggLightObject.cpp index f24a2159..b19e3a0f 100644 --- a/src/egg/gfx/eggLightObject.cpp +++ b/src/egg/gfx/eggLightObject.cpp @@ -286,9 +286,9 @@ void LightObject::CopyFromG3D( } } else { // TODO - ClearFlag4(); + ClearFlag2(); if (optObj != nullptr) { - optObj->ClearFlag4(); + optObj->ClearFlag2(); } } } @@ -367,7 +367,7 @@ bool LightObject::ApplyAnmResultB(const nw4r::g3d::LightAnmResult &res) { mShininess = res.shininess; return true; } else { - ClearFlag4(); + ClearFlag2(); return false; } } From 263813895ae1319ba125a4286c38892b0b478db5 Mon Sep 17 00:00:00 2001 From: robojumper Date: Mon, 24 Mar 2025 00:25:00 +0100 Subject: [PATCH 37/62] FogManager OK --- configure.py | 2 +- src/egg/gfx/eggFogManager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.py b/configure.py index 79cd5a4e..b6aba830 100644 --- a/configure.py +++ b/configure.py @@ -877,7 +877,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggDrawPathDOF.cpp"), Object(Matching, "egg/gfx/eggDrawPathLightMap.cpp"), Object(NonMatching, "egg/gfx/eggFog.cpp"), - Object(NonMatching, "egg/gfx/eggFogManager.cpp"), + Object(Matching, "egg/gfx/eggFogManager.cpp"), Object(NonMatching, "egg/gfx/eggFrustum.cpp"), Object(NonMatching, "egg/gfx/eggG3DUtility.cpp"), Object(NonMatching, "egg/gfx/eggGfxEngine.cpp"), diff --git a/src/egg/gfx/eggFogManager.cpp b/src/egg/gfx/eggFogManager.cpp index 44d504fb..8108162e 100644 --- a/src/egg/gfx/eggFogManager.cpp +++ b/src/egg/gfx/eggFogManager.cpp @@ -6,7 +6,7 @@ namespace EGG { -FogManager::FogManager(u16 num) : mFlag(0), mCount(num), mCount2(num) { +FogManager::FogManager(const u16 num) : mFlag(0), mCount(num), mCount2(num) { mpFog = new Fog[num]; } From 31728178d9d83de43cb1dfd9a1ff1f8cf568edd6 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sun, 23 Mar 2025 21:01:17 -0400 Subject: [PATCH 38/62] More PostEffect Progress --- config/SOUE01/symbols.txt | 20 +++++----- configure.py | 2 +- include/egg/gfx/eggPostEffectBase.h | 21 +++++++---- include/egg/gfx/eggPostEffectMaskDOF.h | 6 +-- src/egg/gfx/eggPostEffectBase.cpp | 5 ++- src/egg/gfx/eggPostEffectBlur.cpp | 13 ++++--- src/egg/gfx/eggPostEffectMaskDOF.cpp | 51 +++++++++++++++++++++++++- 7 files changed, 88 insertions(+), 30 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index cd6d5f2a..e64d6945 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26713,13 +26713,13 @@ 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 -FUN_804b10c0 = .text:0x804B10C0; // type:function size:0x330 -FUN_804b13f0 = .text:0x804B13F0; // type:function size:0x174 -FUN_804b1570 = .text:0x804B1570; // type:function size:0x64C -FUN_804b1bc0 = .text:0x804B1BC0; // type:function size:0x8 -FUN_804b1bd0 = .text:0x804B1BD0; // type:function size:0x8 -FUN_804b1be0 = .text:0x804B1BE0; // type:function size:0x8 +__ct__Q23EGG17PostEffectMaskDOFFv = .text:0x804B0F60; // type:function size:0x160 +setUpGradation__Q23EGG17PostEffectMaskDOFFv = .text:0x804B10C0; // type:function size:0x330 +draw__Q23EGG17PostEffectMaskDOFFff = .text:0x804B13F0; // type:function size:0x174 +setMaterialInternal__Q23EGG17PostEffectMaskDOFFv = .text:0x804B1570; // type:function size:0x64C +getNearColor__Q23EGG17PostEffectMaskDOFFv = .text:0x804B1BC0; // type:function size:0x8 +getFarColor__Q23EGG17PostEffectMaskDOFFv = .text:0x804B1BD0; // type:function size:0x8 +getCenterColor__Q23EGG17PostEffectMaskDOFFv = .text:0x804B1BE0; // type:function size:0x8 __ct__Q23EGG16PostEffectSimpleFv = .text:0x804B1BF0; // type:function size:0x5C setMaterialInternal__Q23EGG16PostEffectSimpleFv = .text:0x804B1C50; // type:function size:0x208 Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen = .text:0x804B1E60; // type:function size:0x1DC @@ -37380,7 +37380,7 @@ __vt__Q23EGG14PostEffectBlur = .data:0x8056F170; // type:object size:0x1C __vt__Q23EGG20PostEffectBlurGather = .data:0x8056F190; // type:object size:0x1C __vt__Q23EGG14PostEffectUnk2 = .data:0x8056F1B0; // type:object size:0x1C __vt__Q23EGG14PostEffectMask = .data:0x8056F1D0; // type:object size:0x1C -lbl_8056F1F0 = .data:0x8056F1F0; // type:object size:0x1C +__vt__Q23EGG17PostEffectMaskDOF = .data:0x8056F1F0; // type:object size:0x1C __vt__Q23EGG16PostEffectSimple = .data:0x8056F210; // type:object size:0x1C sTVModeInfo__Q23EGG6Screen = .data:0x8056F230; // type:object size:0x24 data:2byte __vt__Q23EGG6Screen = .data:0x8056F254; // type:object size:0x14 @@ -48166,8 +48166,8 @@ lbl_8057F7BC = .sdata2:0x8057F7BC; // type:object size:0x4 data:float lbl_8057F7C0 = .sdata2:0x8057F7C0; // type:object size:0x4 data:float lbl_8057F7C8 = .sdata2:0x8057F7C8; // type:object size:0x4 data:float lbl_8057F7CC = .sdata2:0x8057F7CC; // type:object size:0x4 data:float -lbl_8057F7D0 = .sdata2:0x8057F7D0; // type:object size:0x4 -lbl_8057F7D4 = .sdata2:0x8057F7D4; // type:object size:0x4 +sColorNear__3EGG = .sdata2:0x8057F7D0; // type:object size:0x4 +sColorFar__3EGG = .sdata2:0x8057F7D4; // type:object size:0x4 lbl_8057F7D8 = .sdata2:0x8057F7D8; // type:object size:0x4 data:float lbl_8057F7DC = .sdata2:0x8057F7DC; // type:object size:0x4 data:float lbl_8057F7E0 = .sdata2:0x8057F7E0; // type:object size:0x4 data:float diff --git a/configure.py b/configure.py index 79cd5a4e..c681fdd7 100644 --- a/configure.py +++ b/configure.py @@ -890,7 +890,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggLightTextureMgr.cpp"), Object(NonMatching, "egg/gfx/eggModelEx.cpp"), Object(Matching, "egg/gfx/eggPostEffectBase.cpp"), - Object(NonMatching, "egg/gfx/eggPostEffectBlur.cpp"), + Object(Matching, "egg/gfx/eggPostEffectBlur.cpp"), Object(Matching, "egg/gfx/eggPostEffectBlurGather.cpp"), Object(NonMatching, "egg/gfx/eggPostEffectUnk2.cpp"), # Unknown Object(Matching, "egg/gfx/eggPostEffectMask.cpp"), diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index 0e940200..7a2cfc0d 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -5,6 +5,7 @@ #include "egg/gfx/eggCapTexture.h" #include "egg/gfx/eggScreen.h" #include "egg/math/eggMath.h" +#include "egg/math/eggRotation.h" #include "nw4r/math/math_types.h" #include "rvl/GX/GXTypes.h" @@ -22,15 +23,19 @@ public: static void setProjection(const EGG::Screen &screen); + f32 getRot() const { + return mRotation; + } + protected: - u32 field_0x00; // at 0x0 - CapTextureWrapper mTex1; // at 0x4 - CapTextureWrapper mTex2; // at 0xC - f32 mOffsetX; // at 0x14 - f32 mOffsetY; // at 0x18 - f32 mScaleX; // at 0x1C - f32 mScaleY; // at 0x20 - f32 mRotation; // at 0x24 + u32 field_0x00; // at 0x0 + CapTextureWrapper mTex1; // at 0x4 + CapTextureWrapper mTex2; // at 0xC + f32 mOffsetX; // at 0x14 + f32 mOffsetY; // at 0x18 + f32 mScaleX; // at 0x1C + f32 mScaleY; // at 0x20 + EGG::Rotation mRotation; // at 0x24 PostEffectBase(); virtual ~PostEffectBase() {} // at 0x8 diff --git a/include/egg/gfx/eggPostEffectMaskDOF.h b/include/egg/gfx/eggPostEffectMaskDOF.h index 5faca35a..56ca76d1 100644 --- a/include/egg/gfx/eggPostEffectMaskDOF.h +++ b/include/egg/gfx/eggPostEffectMaskDOF.h @@ -16,9 +16,9 @@ public: virtual void setMaterialInternal() override; virtual ~PostEffectMaskDOF() {} - const GXColor &getNearColor(); - const GXColor &getFarColor(); - const GXColor &getCenterColor(); + static const GXColor &getNearColor(); + static const GXColor &getFarColor(); + static const GXColor &getCenterColor(); private: /* 0x2C */ u8 field_0x2C; diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp index 2b2993d7..e7dbd1cb 100644 --- a/src/egg/gfx/eggPostEffectBase.cpp +++ b/src/egg/gfx/eggPostEffectBase.cpp @@ -122,8 +122,11 @@ void PostEffectBase::lerpColor(GXColor &out, const GXColor &c1, const GXColor &c } void PostEffectBase::getBaseTexMtx(nw4r::math::MTX34 *mtx) const { + // Feels wrong -> maybe an inline with rotation and pi + f32 rot = Math::pi(); f32 sin, cos; - nw4r::math::SinCosRad(&sin, &cos, mRotation * M_PI); + nw4r::math::SinCosRad(&sin, &cos, rot * mRotation); + f32 zero = 0.0f; f32 scale = 1.0f; f32 f8 = zero - 0.5f; diff --git a/src/egg/gfx/eggPostEffectBlur.cpp b/src/egg/gfx/eggPostEffectBlur.cpp index d94e0692..79d12e8a 100644 --- a/src/egg/gfx/eggPostEffectBlur.cpp +++ b/src/egg/gfx/eggPostEffectBlur.cpp @@ -50,11 +50,12 @@ void PostEffectBlur::drawInternal(u8 kernelIdx, u8 p2, f32 f1, f32 f2) { nw4r::math::MTX34 mtx; const Stage &k = field_0x38[kernelIdx]; - f32 f4 = k.field_0x0C * f1; - f32 f3 = k.field_0x0C * f2; - f32 rad1 = k.field_0x08 - mRotation * Math::pi(); + f32 tx = k.field_0x0C * f1; + f32 ty = k.field_0x0C * f2; + f32 rad1 = k.field_0x08 - Math::pi() * mRotation; + f32 abc = 2.f * Math::pi() / k.field_0x00; + int unk_00_scale = (p2 & 0x1F) * 8; - f32 abc = (2.f * Math::pi() / k.field_0x00); u8 numTexGens = k.field_0x00 - unk_00_scale; if (numTexGens > 8) { @@ -70,8 +71,8 @@ void PostEffectBlur::drawInternal(u8 kernelIdx, u8 p2, f32 f1, f32 f2) { nw4r::math::SinCosRad(&sin, &cos, rad1 + abc * unk_00_scale); nw4r::math::MTX34 m( // clang-format off - 1.0f, 0.0f, cos * f4, 0.0f, - 0.0f, 1.0f, sin * f3, 0.0f, + 1.0f, 0.0f, cos * tx, 0.0f, + 0.0f, 1.0f, sin * ty, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f // clang-format on ); diff --git a/src/egg/gfx/eggPostEffectMaskDOF.cpp b/src/egg/gfx/eggPostEffectMaskDOF.cpp index 7e9bc43a..fce42b94 100644 --- a/src/egg/gfx/eggPostEffectMaskDOF.cpp +++ b/src/egg/gfx/eggPostEffectMaskDOF.cpp @@ -39,7 +39,56 @@ PostEffectMaskDOF::PostEffectMaskDOF() field_0x00 = 0; } -void PostEffectMaskDOF::setUpGradation() {} +void PostEffectMaskDOF::setUpGradation() { + for (int i = 0; i < 3; i++) { + const u16 width = mpCpuTexArr[i]->getWidth(); + const int mid = width / 2; + for (u16 x = 0; x < mid; x++) { + f32 val = 1.f - (f32)x / (mid - 1); + + switch (i) { + case 1: val *= val; break; + case 2: + val *= val; + val *= val; + break; + } + + GXColor clr1, clr2; + lerpColor(clr1, getCenterColor(), getNearColor(), val); + lerpColor(clr2, getCenterColor(), getFarColor(), val); + + mpCpuTexArr[i]->setColor(x, 0, clr1); + mpCpuTexArr[i]->setColor(x, 1, clr1); + mpCpuTexArr[i]->setColor((width - 1) - x, 0, clr2); + mpCpuTexArr[i]->setColor((width - 1) - x, 1, clr2); + } + mpCpuTexArr[i]->flush(); + } + + const u16 width = mpCpuTex->getWidth() / 2; + for (u16 y = 0; y < mpCpuTex->getHeight(); y++) { + const f32 fy = ((f32)y / mpCpuTex->getHeight()); + for (u16 x = 0; x < width; x++) { + f32 fx = (f32)x / width; + f32 ratio = fx / (1.f - fy); + + if (ratio > 1.f) { + ratio = 1.f; + } else if (ratio < 0.f) { + ratio = 0.f; + } + ratio *= ratio; + ratio *= ratio; + GXColor clr1, clr2; + lerpColor(clr1, getCenterColor(), getNearColor(), ratio); + lerpColor(clr2, getCenterColor(), getFarColor(), ratio); + mpCpuTex->setColor((width - 1) - x, y, clr1); + mpCpuTex->setColor(width + x, y, clr2); + } + } + mpCpuTex->flush(); +} void PostEffectMaskDOF::draw(f32 width, f32 height) { setMaterialInternal(); From 3e7dd3283af2fda9fb4fc67768d5b6c08325fc18 Mon Sep 17 00:00:00 2001 From: robojumper Date: Mon, 24 Mar 2025 23:40:14 +0100 Subject: [PATCH 39/62] Start StateEfb --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 9 ++++--- include/egg/gfx/eggStateEfb.h | 27 +++++++++++++++++++++ include/egg/gfx/eggStateGX.h | 2 +- src/egg/gfx/eggStateEfb.cpp | 44 ++++++++++++++++++++++++++++++++++- src/egg/gfx/eggStateGX.cpp | 2 +- 6 files changed, 77 insertions(+), 8 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 9c7b55a7..84c47baf 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2347,6 +2347,7 @@ egg/gfx/eggStateEfb.cpp: .text start:0x804B3DA0 end:0x804B460C .sdata start:0x80574F60 end:0x80574F68 .sbss start:0x80576898 end:0x805768A0 + .sdata2 start:0x8057F868 end:0x8057F890 .bss start:0x80675010 end:0x806750A0 egg/gfx/eggStateGX.cpp: diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index d99e2921..2b094dbd 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -49806,11 +49806,10 @@ sMtx__3EGG = .bss:0x80674EC0; // type:object size:0x30 data:float lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0xC data:float @LOCAL@Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen@defaultRoot = .bss:0x80674F00; // type:object size:0x88 data:4byte sScreen__Q23EGG16ScreenEffectBase = .bss:0x80674F88; // type:object size:0x88 -lbl_80675010 = .bss:0x80675010; // type:object size:0x30 -lbl_80675040 = .bss:0x80675040; // type:object size:0x14 data:float -lbl_80675054 = .bss:0x80675054; // type:object size:0x4 data:float -lbl_80675058 = .bss:0x80675058; // type:object size:0x18 data:float -lbl_80675070 = .bss:0x80675070; // type:object size:0x30 data:float +spBufferSet__Q23EGG8StateEfb = .bss:0x80675010; // type:object size:0x30 +sWorkSpaceV__Q23EGG8StateEfb = .bss:0x80675040; // type:object size:0x18 data:float +sWorkSpaceHideV__Q23EGG8StateEfb = .bss:0x80675058; // type:object size:0x18 data:float +sUnkBuffer__Q23EGG8StateEfb = .bss:0x80675070; // type:object size:0x18 data:float sDefaultTexObj__Q23EGG7StateGX = .bss:0x806750A0; // type:object size:0x20 s_tmem_layout__Q23EGG7StateGX = .bss:0x806750C0; // type:object size:0xA8 data:4byte s_cacheGX__Q23EGG7StateGX = .bss:0x80675168; // type:object size:0x18 diff --git a/include/egg/gfx/eggStateEfb.h b/include/egg/gfx/eggStateEfb.h index fdecd35a..97e82605 100644 --- a/include/egg/gfx/eggStateEfb.h +++ b/include/egg/gfx/eggStateEfb.h @@ -1,11 +1,38 @@ #ifndef EGG_STATE_EFB_H #define EGG_STATE_EFB_H +#include "common.h" +#include "egg/egg_types.h" + namespace EGG { class StateEfb { + enum BufferType { + BUFFER_0, + BUFFER_1, + BUFFER_2, + BUFFER_3, + + BUFFER_MAX, + }; + + struct Buffer { + TextureBuffer *buf; + u32 userData; + u32 field_0x08; + }; + + static Buffer spBufferSet[BUFFER_MAX]; + static f32 sWorkSpaceV[6]; + static f32 sWorkSpaceHideV[6]; + static f32 sUnkBuffer[6]; // unk name + static s32 sWorkBuffer; + static s32 sPushCount; + static u32 sFlag; + public: static void Clean(); + static bool releaseEfb(BufferType type, u32 userData); }; } // namespace EGG diff --git a/include/egg/gfx/eggStateGX.h b/include/egg/gfx/eggStateGX.h index 9dcdf342..251d864e 100644 --- a/include/egg/gfx/eggStateGX.h +++ b/include/egg/gfx/eggStateGX.h @@ -89,7 +89,7 @@ public: static CacheGX &GXSetDstAlpha_(bool, u8); static void GXSetProjection_(Mtx44, GXProjectionType); static void GXSetProjectionv_(const f32 *); - static void GXSetViewport_(f32, f32, f32, f32, f32, f32); + static void GXSetViewport_(f32 ox, f32 oy, f32 sx, f32 sy, f32 near, f32 far); static void GXSetScissor_(u32, u32, u32, u32); static void GXSetScissorBoxOffset_(s32, s32); diff --git a/src/egg/gfx/eggStateEfb.cpp b/src/egg/gfx/eggStateEfb.cpp index 25f2dbbb..39a4a588 100644 --- a/src/egg/gfx/eggStateEfb.cpp +++ b/src/egg/gfx/eggStateEfb.cpp @@ -1,3 +1,45 @@ #include "egg/gfx/eggStateEfb.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/gfx/eggTextureBuffer.h" + +namespace EGG { + +StateEfb::Buffer StateEfb::spBufferSet[BUFFER_MAX]; +f32 StateEfb::sWorkSpaceV[6]; +f32 StateEfb::sWorkSpaceHideV[6]; +f32 StateEfb::sUnkBuffer[6]; + +u32 StateEfb::sFlag = 4; +s32 StateEfb::sWorkBuffer = -1; + +s32 StateEfb::sPushCount; + +void StateEfb::Clean() { + sFlag &= ~(1 | 2); + sWorkBuffer = -1; + sPushCount = 0; + + for (u32 i = 0; i < ARRAY_LENGTH(spBufferSet); i++) { + spBufferSet[i].field_0x08 = 0; + } + + for (u32 i = 0; i < ARRAY_LENGTH(sWorkSpaceV); i++) { + sWorkSpaceV[i] = 0.0f; + sWorkSpaceHideV[i] = 0.0f; + } +} + +bool StateEfb::releaseEfb(BufferType type, u32 userData) { + if (spBufferSet[type].buf != nullptr && spBufferSet[type].userData == userData) { + spBufferSet[type].buf->free(); + spBufferSet[type].buf = nullptr; + spBufferSet[type].userData = 0; + spBufferSet[type].field_0x08 = 0; + return true; + } else { + return false; + } +} + +} // namespace EGG diff --git a/src/egg/gfx/eggStateGX.cpp b/src/egg/gfx/eggStateGX.cpp index f364b81a..fc56e29e 100644 --- a/src/egg/gfx/eggStateGX.cpp +++ b/src/egg/gfx/eggStateGX.cpp @@ -34,7 +34,7 @@ static const f32 identity[3][4] = { namespace EGG { -GXTexObj StateGX::sDefaultTexObj; +GXTexObj ALIGN_DECL(32) StateGX::sDefaultTexObj; StateGX::MemLayout StateGX::s_tmem_layout; StateGX::CacheGX StateGX::s_cacheGX; From a8327ffc92eed8f5901a7dce08648de36fd50f6c Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Mon, 24 Mar 2025 21:28:54 -0400 Subject: [PATCH 40/62] Im tired --- include/egg/gfx/eggCapTexture.h | 4 ++ include/egg/gfx/eggCpuTexture.h | 4 ++ include/egg/gfx/eggPostEffectBase.h | 2 +- src/egg/gfx/eggPostEffectMaskDOF.cpp | 7 +-- src/egg/gfx/eggScreenEffectBlur.cpp | 64 +++++++++++++++++++++++++++- 5 files changed, 75 insertions(+), 6 deletions(-) diff --git a/include/egg/gfx/eggCapTexture.h b/include/egg/gfx/eggCapTexture.h index bf6d1f7b..955504eb 100644 --- a/include/egg/gfx/eggCapTexture.h +++ b/include/egg/gfx/eggCapTexture.h @@ -38,6 +38,10 @@ public: mClearColor = clr; } + void setCopyFilter(const CopyFilter &filt) { + mCopyFilterArg = filt; + } + private: /* 0x18 */ u8 mCapFlags; /* 0x19 */ GXColor mClearColor; diff --git a/include/egg/gfx/eggCpuTexture.h b/include/egg/gfx/eggCpuTexture.h index 11096550..a3e4db22 100644 --- a/include/egg/gfx/eggCpuTexture.h +++ b/include/egg/gfx/eggCpuTexture.h @@ -68,6 +68,10 @@ public: u16 getHeight() const { return mHeight; } + // Needed for PostEffectMaskDOF::setUpGradation + u16 getHeight2() { + return mHeight; + } void setHeight(u16 h) { mHeight = h; } diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index 7a2cfc0d..16f85642 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -27,7 +27,7 @@ public: return mRotation; } -protected: +public: u32 field_0x00; // at 0x0 CapTextureWrapper mTex1; // at 0x4 CapTextureWrapper mTex2; // at 0xC diff --git a/src/egg/gfx/eggPostEffectMaskDOF.cpp b/src/egg/gfx/eggPostEffectMaskDOF.cpp index fce42b94..59104d51 100644 --- a/src/egg/gfx/eggPostEffectMaskDOF.cpp +++ b/src/egg/gfx/eggPostEffectMaskDOF.cpp @@ -68,10 +68,11 @@ void PostEffectMaskDOF::setUpGradation() { const u16 width = mpCpuTex->getWidth() / 2; for (u16 y = 0; y < mpCpuTex->getHeight(); y++) { - const f32 fy = ((f32)y / mpCpuTex->getHeight()); + f32 fy = (f32)y / mpCpuTex->getHeight2(); for (u16 x = 0; x < width; x++) { - f32 fx = (f32)x / width; - f32 ratio = fx / (1.f - fy); + // Don't even have to use this one! + (void)(f32)width; + f32 ratio = ((f32)x / width) / (1.f - fy); if (ratio > 1.f) { ratio = 1.f; diff --git a/src/egg/gfx/eggScreenEffectBlur.cpp b/src/egg/gfx/eggScreenEffectBlur.cpp index c445b216..25b379a7 100644 --- a/src/egg/gfx/eggScreenEffectBlur.cpp +++ b/src/egg/gfx/eggScreenEffectBlur.cpp @@ -1,6 +1,7 @@ #include "egg/gfx/eggScreenEffectBlur.h" #include "common.h" +#include "egg/gfx/eggCpuTexture.h" #include "egg/gfx/eggDrawGX.h" #include "egg/gfx/eggPostEffectBase.h" #include "egg/gfx/eggPostEffectBlur.h" // IWYU pragma: keep @@ -12,6 +13,8 @@ #include "rvl/GX/GXTypes.h" #include "rvl/MTX/mtx.h" +#include + namespace EGG { static const GXColor sDefaultColor = {0, 0, 0, 0xFF}; @@ -41,9 +44,66 @@ ScreenEffectBlur::~ScreenEffectBlur() { delete mpUnk2; delete mpBlur; } - +static const CopyFilter copyFilter = { + {0x15, 0, 0, 0x16, 0, 0x15, 0} +}; void ScreenEffectBlur::fn_804B32B0() { - // Oh god + if (mFlag & 1) { + StateGX::invalidateTexAllGX(); + PostEffectBase::setProjection(GetScreen()); + const Screen::DataEfb &efb = GetScreen().GetDataEfb(); + u16 x1 = efb.vp.x1; + u16 y1 = efb.vp.y1; + f32 sizeX = (u16)sScreen.GetSize().x * field_0x10; + f32 sizeY = (u16)sScreen.GetSize().y * field_0x10; + u16 x2 = efb.vp.x2 * field_0x10; + u16 y2 = efb.vp.y2 * field_0x10; + + StateGX::ScopedColor _clr(true); + StateGX::ScopedAlpha _alpha(false); + StateGX::ScopedDither _dither(false); + TextureBuffer *pTex0 = NULL; + if (field_0x0C & 1) { + pTex0 = TextureBuffer::alloc(x2, y2, GX_TF_RGBA8); + pTex0->capture(x1, y1, 0, GX_TF_RGBA8); + } + TextureBuffer *pTex1 = TextureBuffer::alloc(x2, y2, GX_TF_IA8); + pTex1->setMinFilt(GX_NEAR); + pTex1->setMagFilt(GX_NEAR); + pTex1->capture(x1, y1, false, GX_TF_Z16); + + // . . . + if (field_0x0C & 2) { + TextureBuffer *pTex2 = TextureBuffer::alloc(x2, y2, GX_TF_RGBA8); + pTex2->onCapFlag(0x8); + pTex2->setCopyFilter(copyFilter); + pTex2->capture(x1, y1, false, GX_CTF_R8); + u8 val = field_0x18 * 255.f; + GXColor clr = {val, val, val, val}; + mpBlur->setStage0Color(clr); + mpBlur->setStage0F(field_0x1C); + mpBlur->mTex1 = (PostEffectBase::CapTextureWrapper){pTex2, GX_TEXMAP1}; + mpBlur->draw(sizeX * 1.0f, sizeY * 1.0f); + pTex2->free(); + } + // . . . + + mpCpuTexture = TextureBuffer::alloc(x2, y2, GX_TF_I8); + mpCpuTexture->onCapFlag(0x8); + mpCpuTexture->setCopyFilter(copyFilter); + mpCpuTexture->capture(x1, y1, false, GX_CTF_R8); + pTex1->free(); + + if (field_0x0C & 1) { + nw4r::math::MTX34 m; + PSMTXScale(m, sizeY, sizeY, 1.f); + pTex0->load(GX_TEXMAP0); + DrawGX::BeginDrawScreen(true, true, false); + DrawGX::SetBlendMode(DrawGX::BLEND_14); + DrawGX::DrawDL16(m, DrawGX::WHITE); + pTex0->free(); + } + } } void ScreenEffectBlur::fn_804B3710() { From 8c8676aed1141d47fc529fc447967885527835ac Mon Sep 17 00:00:00 2001 From: robojumper Date: Tue, 25 Mar 2025 22:20:21 +0100 Subject: [PATCH 41/62] StateEfb less one regswap --- config/SOUE01/symbols.txt | 14 +- include/egg/gfx/eggFrustum.h | 4 +- include/egg/gfx/eggGlobalDrawState.h | 2 +- include/egg/gfx/eggStateEfb.h | 9 ++ src/egg/gfx/eggCamera.cpp | 3 +- src/egg/gfx/eggStateEfb.cpp | 193 ++++++++++++++++++++++++++- 6 files changed, 211 insertions(+), 14 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 2b094dbd..ad595dbb 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26759,11 +26759,11 @@ GetBinarySize__Q23EGG33IBinaryCFv = .text:0x804B3D50; Clean__Q23EGG8StateEfbFv = .text:0x804B3DA0; // type:function size:0x78 captureEfb__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypebUl = .text:0x804B3E20; // type:function size:0x3C8 releaseEfb__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypeUl = .text:0x804B41F0; // type:function size:0x7C -FUN_804b4270 = .text:0x804B4270; // type:function size:0x98 -FUN_804b4310 = .text:0x804B4310; // type:function size:0x23C -FUN_804b4550 = .text:0x804B4550; // type:function size:0xA0 -FUN_804b45f0 = .text:0x804B45F0; // type:function size:0xC -FUN_804b4600 = .text:0x804B4600; // type:function size:0xC +fn_804B4270__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypeUl = .text:0x804B4270; // type:function size:0x98 +fn_804B4310__Q23EGG8StateEfbFQ33EGG8StateEfb10BufferTypeUl = .text:0x804B4310; // type:function size:0x23C +fn_804B4550__Q23EGG8StateEfbFv = .text:0x804B4550; // type:function size:0xA0 +GetShouldCapture__Q23EGG8StateEfbFv = .text:0x804B45F0; // type:function size:0xC +GetUseTfRgb565__Q23EGG8StateEfbFv = .text:0x804B4600; // type:function size:0xC texRegionCallback__24@unnamed@eggStateGX_cpp@FPC9_GXTexObj11_GXTexMapID = .text:0x804B4610; // type:function size:0x28 initialize__Q23EGG7StateGXFUsUs8_GXColor11_GXPixelFmt = .text:0x804B4640; // type:function size:0x114 frameInit__Q23EGG7StateGXFv = .text:0x804B4760; // type:function size:0xA8 @@ -39835,8 +39835,8 @@ lbl_80574F3C = .sdata:0x80574F3C; // type:object size:0xC sByteCodeCalcStr__Q23EGG7ModelEx = .sdata:0x80574F48; // type:object size:0x4 data:4byte lbl_80574F50 = .sdata:0x80574F50; // type:object size:0x8 data:string sByteCodeMixStr__Q23EGG7ModelEx = .sdata:0x80574F58; // type:object size:0x4 data:4byte -lbl_80574F60 = .sdata:0x80574F60; // type:object size:0x4 data:4byte -lbl_80574F64 = .sdata:0x80574F64; // type:object size:0x4 data:4byte +sFlag__Q23EGG8StateEfb = .sdata:0x80574F60; // type:object size:0x4 data:4byte +sWorkBuffer__Q23EGG8StateEfb = .sdata:0x80574F64; // type:object size:0x4 data:4byte sAudioRmtSpeakerWpadVolume__Q23EGG18AudioRmtSpeakerMgr = .sdata:0x80574F68; // type:object size:0x1 data:byte sHBFadeframe__Q33EGG12AudioUtility3HBM = .sdata:0x80574F70; // type:object size:0x4 data:4byte fragmentID = .sdata:0x80574F78; // type:object size:0x4 scope:local data:4byte diff --git a/include/egg/gfx/eggFrustum.h b/include/egg/gfx/eggFrustum.h index 877a4940..5165935c 100644 --- a/include/egg/gfx/eggFrustum.h +++ b/include/egg/gfx/eggFrustum.h @@ -24,8 +24,8 @@ public: CANVASMODE_0, CANVASMODE_1, }; - -protected: + + protected: ProjectionType mProjType; // at 0x0 CanvasMode mCanvasMode; // at 0x4 nw4r::math::VEC2 mSize; // at 0x8 diff --git a/include/egg/gfx/eggGlobalDrawState.h b/include/egg/gfx/eggGlobalDrawState.h index a85dfbb6..19f38fff 100644 --- a/include/egg/gfx/eggGlobalDrawState.h +++ b/include/egg/gfx/eggGlobalDrawState.h @@ -31,10 +31,10 @@ public: sDrawFlag &= ~flag; } + static Screen const *spScreen; private: static u16 sCameraId; static u32 sDrawFlag; - static Screen const *spScreen; // unknown static nw4r::math::MTX34 sMtx; diff --git a/include/egg/gfx/eggStateEfb.h b/include/egg/gfx/eggStateEfb.h index 97e82605..eabf22d2 100644 --- a/include/egg/gfx/eggStateEfb.h +++ b/include/egg/gfx/eggStateEfb.h @@ -30,9 +30,18 @@ class StateEfb { static s32 sPushCount; static u32 sFlag; + static f32 *fn_804B4550(); + static bool GetShouldCapture(); + static bool GetUseTfRgb565(); + public: static void Clean(); + static TextureBuffer *captureEfb(BufferType type, bool, u32 userData); static bool releaseEfb(BufferType type, u32 userData); + + // Unknown names + static void fn_804B4270(BufferType type, u32 userData); + static void fn_804B4310(BufferType type, u32 userData); }; } // namespace EGG diff --git a/src/egg/gfx/eggCamera.cpp b/src/egg/gfx/eggCamera.cpp index ed474b66..2417ba89 100644 --- a/src/egg/gfx/eggCamera.cpp +++ b/src/egg/gfx/eggCamera.cpp @@ -78,14 +78,13 @@ OrthoCamera::OrthoCamera() { } void OrthoCamera::update_parms() { - // NONMATCHING f32 z = field_0x8C; f32 sin = field_0x88.sin(); f32 cos = field_0x88.cos(); - mPos(2) = z; mPos(1) = mAt(1); mPos(0) = mAt(0); + mPos(2) = z; mUp(2) = 0.f; mUp(1) = cos; mUp(0) = sin; diff --git a/src/egg/gfx/eggStateEfb.cpp b/src/egg/gfx/eggStateEfb.cpp index 39a4a588..919d324e 100644 --- a/src/egg/gfx/eggStateEfb.cpp +++ b/src/egg/gfx/eggStateEfb.cpp @@ -1,7 +1,14 @@ #include "egg/gfx/eggStateEfb.h" #include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggGlobalDrawState.h" +#include "egg/gfx/eggScreen.h" +#include "egg/gfx/eggStateGX.h" #include "egg/gfx/eggTextureBuffer.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" namespace EGG { @@ -19,17 +26,111 @@ void StateEfb::Clean() { sFlag &= ~(1 | 2); sWorkBuffer = -1; sPushCount = 0; - + for (u32 i = 0; i < ARRAY_LENGTH(spBufferSet); i++) { spBufferSet[i].field_0x08 = 0; } - + for (u32 i = 0; i < ARRAY_LENGTH(sWorkSpaceV); i++) { sWorkSpaceV[i] = 0.0f; sWorkSpaceHideV[i] = 0.0f; } } +TextureBuffer *StateEfb::captureEfb(BufferType type, bool noTransparencyMaybe, u32 userData) { + // NONMATCHING - GPR regswaps + const Screen::DataEfb &efb = GlobalDrawState::getScreen().GetDataEfb(); + + if (spBufferSet[type].buf == nullptr) { + f32 x1 = efb.vp.x1; + f32 y1 = efb.vp.y1; + + bool doUpscale = false; + bool doCapture = true; + + switch (type) { + case BUFFER_0: + case BUFFER_1: { + f32 arg; + if (type == BUFFER_0) { + arg = 0.25f; + } else { + arg = 0.5f; + } + + sWorkSpaceV[2] = efb.vp.x2 * arg; + sWorkSpaceV[3] = efb.vp.y2 * arg; + + sWorkSpaceV[2] = (int)sWorkSpaceV[2] + (int)sWorkSpaceV[2] % 2; + sWorkSpaceV[3] = (int)sWorkSpaceV[3] + (int)sWorkSpaceV[3] % 2; + + if (sWorkSpaceV[2] > sWorkSpaceV[3]) { + sWorkSpaceV[3] = sWorkSpaceV[2]; + } else { + sWorkSpaceV[2] = sWorkSpaceV[3]; + } + + sWorkSpaceV[0] = 640.0f - sWorkSpaceV[2]; + sWorkSpaceHideV[0] = sWorkSpaceV[0]; + sWorkSpaceV[1] = 528.0f - sWorkSpaceV[3]; + sWorkSpaceHideV[1] = sWorkSpaceV[1]; + + sWorkSpaceHideV[2] = sWorkSpaceV[2] - (640 - StateGX::s_widthEfb); + sWorkSpaceHideV[3] = sWorkSpaceV[3] - (528 - StateGX::s_heightEfb); + + if (sWorkSpaceHideV[2] < 0.0f) { + sWorkSpaceHideV[2] = 0.0f; + } + if (sWorkSpaceHideV[3] < 0.0f) { + sWorkSpaceHideV[3] = 0.0f; + } + + x1 = sWorkSpaceV[0]; + y1 = sWorkSpaceV[1]; + + TextureBuffer *buf = TextureBuffer::alloc(sWorkSpaceHideV[2], sWorkSpaceHideV[3], GX_TF_RGBA8); + spBufferSet[type].buf = buf; + if (spBufferSet[type].buf != nullptr) { + spBufferSet[type].buf->setPixModeSync(false); + } + doCapture = GetShouldCapture(); + break; + } + + case BUFFER_2: + spBufferSet[type].buf = TextureBuffer::alloc(efb.vp.x2, efb.vp.y2, GX_TF_RGBA8); + spBufferSet[type].buf->setPixModeSync(false); + break; + case BUFFER_3: + spBufferSet[type].buf = TextureBuffer::alloc( + efb.vp.x2 / 2.0f, efb.vp.y2 / 2.0f, GetUseTfRgb565() ? GX_TF_RGB565 : GX_TF_RGBA8 + ); + doUpscale = true; + break; + default: break; + } + + if (spBufferSet[type].buf != nullptr) { + spBufferSet[type].userData = userData; + if (noTransparencyMaybe) { + spBufferSet[type].buf->onCapFlag(0x2); + spBufferSet[type].buf->setClearColor((GXColor){0, 0, 0, 0}); + } + if (x1 < 0.0f) { + x1 = 0.0f; + } + if (y1 < 0.0f) { + y1 = 0.0f; + } + if (doCapture) { + spBufferSet[type].buf->capture(x1, y1, doUpscale, -1); + } + } + } + + return spBufferSet[type].buf; +} + bool StateEfb::releaseEfb(BufferType type, u32 userData) { if (spBufferSet[type].buf != nullptr && spBufferSet[type].userData == userData) { spBufferSet[type].buf->free(); @@ -42,4 +143,92 @@ bool StateEfb::releaseEfb(BufferType type, u32 userData) { } } +void StateEfb::fn_804B4270(BufferType type, u32 userData) { + if (type == BUFFER_0) { + if (sWorkBuffer == 1) { + StateEfb::releaseEfb(BUFFER_0, spBufferSet[0].userData); + } + captureEfb(BUFFER_1, false, userData); + sWorkBuffer = 0; + } else if (type == BUFFER_1 && sWorkBuffer != 0) { + captureEfb(BUFFER_0, false, userData); + sWorkBuffer = 1; + } +} + +void StateEfb::fn_804B4310(BufferType type, u32 userData) { + if (sWorkBuffer != -1) { + BufferType i = static_cast(-1); + if (sWorkBuffer == 0) { + i = BUFFER_1; + } else if (sWorkBuffer == 1) { + i = BUFFER_0; + } + + if (spBufferSet[i].userData == userData) { + if (type == BUFFER_0) { + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(true); + StateGX::ScopedDither ditherGuard(false); + + const Screen &parentScreen = GlobalDrawState::getScreen(); + Screen s(parentScreen); + + s.SetFlag(Screen::FLAG_0x40); + s.SetCanvasMode(Screen::CANVASMODE_1); + s.SetProjectionType(Screen::PROJ_ORTHO); + s.SetNearFar(0.0f, 1.0f); + s.SetScale(nw4r::math::VEC3(1.0f, 1.0f, 1.0f)); + s.SetOffset(nw4r::math::VEC2(0.0f, 0.0f)); + + s.SetProjectionGX(); + StateGX::GXSetViewport_( + sWorkSpaceHideV[0], sWorkSpaceHideV[1], sWorkSpaceHideV[2], sWorkSpaceHideV[3], 0.0f, 1.0f + ); + StateGX::GXSetScissor_(sWorkSpaceHideV[0], sWorkSpaceHideV[1], sWorkSpaceHideV[2], sWorkSpaceHideV[3]); + StateGX::GXSetScissorBoxOffset_(0, 0); + + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, parentScreen.GetSize().x, parentScreen.GetSize().y, 1.0f); + + DrawGX::BeginDrawScreen(true, GetShouldCapture(), false); + DrawGX::SetBlendMode(DrawGX::BLEND_14); + if (GetShouldCapture()) { + TextureBuffer *buf = spBufferSet[i].buf; + buf->setFilt(GX_NEAR, GX_NEAR); + buf->load(DrawGX::GetTexMapDefault()); + DrawGX::DrawDL(DrawGX::DL_16, mtx, DrawGX::WHITE); + } + } + releaseEfb((i), spBufferSet[i].userData); + sWorkBuffer = -1; + sPushCount += 1; + } + } +} + +f32 *StateEfb::fn_804B4550() { + const Screen::DataEfb &efb = GlobalDrawState::getScreen().GetDataEfb(); + sUnkBuffer[0] = sWorkSpaceV[0]; + sUnkBuffer[1] = sWorkSpaceV[1]; + sUnkBuffer[2] = efb.vp.x2; + sUnkBuffer[3] = efb.vp.y2; + sUnkBuffer[4] = efb.vp.z1; + sUnkBuffer[5] = efb.vp.z2; + StateGX::GXSetViewport_(sUnkBuffer[0], sUnkBuffer[1], sUnkBuffer[2], sUnkBuffer[3], sUnkBuffer[4], sUnkBuffer[5]); + u32 f[4]; + StateGX::CalculateScreenScissor(sUnkBuffer, f); + StateGX::GXSetScissor_(f[0], f[1], f[2], f[3]); + StateGX::GXSetScissorBoxOffset_(0, 0); + return sUnkBuffer; +} + +bool StateEfb::GetShouldCapture() { + return ((sFlag >> 2) & 1) != 0; +} + +bool StateEfb::GetUseTfRgb565() { + return (sFlag & 8) != 0; +} + } // namespace EGG From e2c8c48b8193074b64a22574212077cd60c570be Mon Sep 17 00:00:00 2001 From: robojumper Date: Tue, 25 Mar 2025 23:26:07 +0100 Subject: [PATCH 42/62] eggCamera OK --- configure.py | 2 +- src/egg/gfx/eggCamera.cpp | 4 ++-- src/egg/gfx/eggStateEfb.cpp | 7 +------ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/configure.py b/configure.py index b0f4d003..0fe32e28 100644 --- a/configure.py +++ b/configure.py @@ -865,7 +865,7 @@ config.libs = [ EGGLib( "gfx", [ - Object(NonMatching, "egg/gfx/eggCamera.cpp"), + Object(Matching, "egg/gfx/eggCamera.cpp"), Object(Matching, "egg/gfx/eggPalette.cpp"), Object(Matching, "egg/gfx/eggTexture.cpp"), Object(NonMatching, "egg/gfx/eggUnk1.cpp"), # Unknown diff --git a/src/egg/gfx/eggCamera.cpp b/src/egg/gfx/eggCamera.cpp index 2417ba89..b99ed73c 100644 --- a/src/egg/gfx/eggCamera.cpp +++ b/src/egg/gfx/eggCamera.cpp @@ -26,8 +26,6 @@ Matrix34f &LookAtCamera::getViewMatrixOld() { } void LookAtCamera::doUpdateMatrix() { - // NONMATCHING - mOtherMtx = mViewMtx; Vector3f right(mPos); @@ -44,6 +42,8 @@ void LookAtCamera::doUpdateMatrix() { f32 ty = -up.dot(mPos); f32 tz = -right.dot(mPos); + f32 t[] = { tx, ty, tz}; + mViewMtx(0, 0) = forward(0); mViewMtx(0, 1) = forward(1); mViewMtx(0, 2) = forward(2); diff --git a/src/egg/gfx/eggStateEfb.cpp b/src/egg/gfx/eggStateEfb.cpp index 919d324e..a21cdf0b 100644 --- a/src/egg/gfx/eggStateEfb.cpp +++ b/src/egg/gfx/eggStateEfb.cpp @@ -51,12 +51,7 @@ TextureBuffer *StateEfb::captureEfb(BufferType type, bool noTransparencyMaybe, u switch (type) { case BUFFER_0: case BUFFER_1: { - f32 arg; - if (type == BUFFER_0) { - arg = 0.25f; - } else { - arg = 0.5f; - } + f32 arg = type == BUFFER_0 ? 0.25f : 0.5f; sWorkSpaceV[2] = efb.vp.x2 * arg; sWorkSpaceV[3] = efb.vp.y2 * arg; From 6c5ed3a266ff5a66f70a269655057d7efbb1afa7 Mon Sep 17 00:00:00 2001 From: robojumper Date: Wed, 26 Mar 2025 23:58:09 +0100 Subject: [PATCH 43/62] A bit of LightTexture --- config/SOUE01/symbols.txt | 26 ++--- include/egg/egg_types.h | 2 +- include/egg/gfx/eggLightObject.h | 17 +++ include/egg/gfx/eggLightTexture.h | 34 +++++- src/egg/gfx/eggLightTexture.cpp | 167 +++++++++++++++++++++++++++++- 5 files changed, 230 insertions(+), 16 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index ad595dbb..45bb9ebe 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26643,8 +26643,8 @@ initialize__Q23EGG12LightTextureFUsPQ23EGG4Heap = .text:0x804AB780; // type:func __ct__Q23EGG12LightTextureFPCcPCQ23EGG19LightTextureManager = .text:0x804AB9F0; // type:function size:0x284 __dt__Q23EGG12LightTextureFv = .text:0x804ABC80; // type:function size:0x90 configure__Q23EGG12LightTextureFv = .text:0x804ABD10; // type:function size:0x6C -EGG__LightTexture__loadTextureData = .text:0x804ABD80; // type:function size:0x10C -EGG__LightTexture__loadCpuTextureFromBti = .text:0x804ABE90; // type:function size:0xC +loadTextureData__Q23EGG12LightTextureFiPv9_GXTexFmt = .text:0x804ABD80; // type:function size:0x10C +loadTextureFromResTimg__Q23EGG12LightTextureFiPQ23EGG7ResTIMG = .text:0x804ABE90; // type:function size:0xC initDrawSetting__Q23EGG12LightTextureFUsUsUsUs = .text:0x804ABEA0; // type:function size:0x1A4 FUN_804ac050 = .text:0x804AC050; // type:function size:0x4C FUN_804ac0a0 = .text:0x804AC0A0; // type:function size:0x34 @@ -29170,7 +29170,7 @@ zeroVec__3EGG = .rodata:0x804FBC88; // type:object size:0xC data:float lbl_804FBC98 = .rodata:0x804FBC98; // type:object size:0xC data:4byte lbl_804FBCA4 = .rodata:0x804FBCA4; // type:object size:0xC data:4byte lbl_804FBCB0 = .rodata:0x804FBCB0; // type:object size:0x10 data:4byte -lbl_804FBCC0 = .rodata:0x804FBCC0; // type:object size:0x48 data:4byte +sCpuTexGradientOp__3EGG = .rodata:0x804FBCC0; // type:object size:0x48 data:4byte lbl_804FBD08 = .rodata:0x804FBD08; // type:object size:0x48 data:float lbl_804FBD50 = .rodata:0x804FBD50; // type:object size:0x10 data:float lbl_804FBD60 = .rodata:0x804FBD60; // type:object size:0x10 data:float @@ -41159,15 +41159,15 @@ lbl_80576830 = .sbss:0x80576830; // type:object size:0x8 data:4byte spScreen__Q23EGG15GlobalDrawState = .sbss:0x80576838; // type:object size:0x4 data:4byte sCameraId__Q23EGG15GlobalDrawState = .sbss:0x8057683C; // type:object size:0x2 data:2byte sDrawFlag__Q23EGG15GlobalDrawState = .sbss:0x80576840; // type:object size:0x4 data:4byte -lbl_80576848 = .sbss:0x80576848; // type:object size:0x2 data:2byte -lbl_8057684A = .sbss:0x8057684A; // type:object size:0x2 data:2byte -lbl_8057684C = .sbss:0x8057684C; // type:object size:0x2 data:2byte -lbl_8057684E = .sbss:0x8057684E; // type:object size:0x2 data:2byte -lbl_80576850 = .sbss:0x80576850; // type:object size:0x2 data:2byte -lbl_80576852 = .sbss:0x80576852; // type:object size:0x2 data:2byte -lbl_80576854 = .sbss:0x80576854; // type:object size:0x2 data:2byte -lbl_80576856 = .sbss:0x80576856; // type:object size:0x2 data:2byte -lbl_80576858 = .sbss:0x80576858; // type:object size:0x4 data:4byte +sDrawWidth__Q23EGG12LightTexture = .sbss:0x80576848; // type:object size:0x2 data:2byte +sDrawHeight__Q23EGG12LightTexture = .sbss:0x8057684A; // type:object size:0x2 data:2byte +sDrawPosX__Q23EGG12LightTexture = .sbss:0x8057684C; // type:object size:0x2 data:2byte +sDrawPosY__Q23EGG12LightTexture = .sbss:0x8057684E; // type:object size:0x2 data:2byte +sTexWidth__Q23EGG12LightTexture = .sbss:0x80576850; // type:object size:0x2 data:2byte +sTexHeight__Q23EGG12LightTexture = .sbss:0x80576852; // type:object size:0x2 data:2byte +sDrawNumX__Q23EGG12LightTexture = .sbss:0x80576854; // type:object size:0x2 data:2byte +sDrawNumY__Q23EGG12LightTexture = .sbss:0x80576856; // type:object size:0x2 data:2byte +spNormalEnvironment__Q23EGG12LightTexture = .sbss:0x80576858; // type:object size:0x4 data:4byte lbl_8057685C = .sbss:0x8057685C; // type:object size:0x1 data:byte lbl_80576860 = .sbss:0x80576860; // type:object size:0x1 data:byte lbl_80576861 = .sbss:0x80576861; // type:object size:0x7 data:byte @@ -49801,7 +49801,7 @@ s_DL__Q23EGG6DrawGX = .bss:0x80674D68; // type:object size:0x90 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 +sCpuTexArray__3EGG = .bss:0x80674E78; // type:object size:0x48 data:4byte sMtx__3EGG = .bss:0x80674EC0; // type:object size:0x30 data:float lbl_80674EF0 = .bss:0x80674EF0; // type:object size:0xC data:float @LOCAL@Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen@defaultRoot = .bss:0x80674F00; // type:object size:0x88 data:4byte diff --git a/include/egg/egg_types.h b/include/egg/egg_types.h index f3f96c61..d72a6037 100644 --- a/include/egg/egg_types.h +++ b/include/egg/egg_types.h @@ -25,7 +25,7 @@ class GXUtility; class IDrawGX; class IScnProc; class IScnProcModel; -class LightObj; +class LightObject; class LightManager; class LightTexture; class LightTextureManager; diff --git a/include/egg/gfx/eggLightObject.h b/include/egg/gfx/eggLightObject.h index afef331c..b2cc876c 100644 --- a/include/egg/gfx/eggLightObject.h +++ b/include/egg/gfx/eggLightObject.h @@ -62,6 +62,10 @@ public: void SetPosAt(nw4r::math::VEC3 const &, nw4r::math::VEC3 const &); void SetDist(f32); + f32 getField0x30() const { + return field_0x30; + } + int getField0x3C() const { return field_0x3C; } @@ -106,13 +110,26 @@ public: return (mFlags & 2) != 0; } + bool CheckFlag0x20() const { + return (mFlags & 0x20) != 0; + } + u16 GetField0x06() const { return field_0x06; } + u16 GetIndex() const { + return mIndex; + } + void UpdatePosAt(LightObject &other) { SetPosAt(other.mPos, other.mAt); } + + const GXColor &GetBlack() const { + return mBlack; + } + private: /* 0x04 */ u16 mIndex; diff --git a/include/egg/gfx/eggLightTexture.h b/include/egg/gfx/eggLightTexture.h index 59bf0907..bb52ed78 100644 --- a/include/egg/gfx/eggLightTexture.h +++ b/include/egg/gfx/eggLightTexture.h @@ -2,9 +2,12 @@ #define EGG_LIGHT_TEXTURE_H #include "common.h" +#include "egg/egg_types.h" #include "egg/gfx/eggCapTexture.h" +#include "egg/gfx/eggTexture.h" #include "egg/math/eggVector.h" #include "egg/prim/eggBinary.h" +#include "rvl/GX/GXTypes.h" namespace EGG { @@ -49,6 +52,13 @@ public: virtual size_t GetBinarySize() const override; static void initialize(u16 textureSize, Heap *pHeap); + static void loadTextureFromResTimg(int index, EGG::ResTIMG *img); + static void initDrawSetting(u16, u16, u16, u16); + void addLight(const EGG::LightObject&); + + void draw(int); + void beginDebugDraw(); + void debugDraw(int); const char *getName() const { return mName1; @@ -58,8 +68,13 @@ public: return mpFloatData[idx]; } + private: + static void fn_804AB270(); + static void fn_804AC0A0(int, int*, int*); + static void loadTextureData(int index, void *data, GXTexFmt fmt); + u8 getByte1(u16 idx) const { return mpByteData1[idx]; } @@ -68,6 +83,11 @@ private: return mpByteData2[idx]; } + // TODO enum + int GetLightType() const { + return mLightType; + } + /* 0x30 */ const LightTextureManager *mpMgr; /* 0x34 */ u8 mNumData; /* 0x35 */ u8 field_0x35; @@ -76,15 +96,27 @@ private: /* 0x38 */ Vector3f field_0x38; /* 0x44 */ f32 *mpFloatData; /* 0x48 */ char *mpByteData1; - /* 0x4C */ char *mpByteData2; + /* 0x4C */ u8 *mpByteData2; /* 0x50 */ f32 field_0x50; /* 0x54 */ char mName1[0x20]; /* 0x74 */ char mName2[0x20]; /* 0x94 */ u16 field_0x94; /* 0x98 */ f32 field_0x98; /* 0x9C */ u8 field_0x9C; + /* 0x9D */ u8 field_0x9D; + /* 0x9E */ u8 field_0x9E; + /* 0x9F */ u8 field_0x9F; static u16 sTextureSize; + + static u16 sDrawWidth; + static u16 sDrawHeight; + static u16 sDrawPosX; + static u16 sDrawPosY; + static u16 sTexWidth; + static u16 sTexHeight; + static u16 sDrawNumX; + static u16 sDrawNumY; static CpuTexture *spNormalEnvironment; }; diff --git a/src/egg/gfx/eggLightTexture.cpp b/src/egg/gfx/eggLightTexture.cpp index 768b447f..b4827998 100644 --- a/src/egg/gfx/eggLightTexture.cpp +++ b/src/egg/gfx/eggLightTexture.cpp @@ -5,8 +5,18 @@ #include "egg/gfx/eggCapTexture.h" #include "egg/gfx/eggCpuTexture.h" #include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggLightObject.h" #include "egg/gfx/eggLightTextureMgr.h" +#include "egg/gfx/eggStateGX.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXBump.h" +#include "rvl/GX/GXGeometry.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTransform.h" #include "rvl/GX/GXTypes.h" +#include "rvl/GX/GXVert.h" +#include "rvl/MTX/mtx.h" +#include "rvl/MTX/mtx44.h" #include @@ -121,7 +131,7 @@ LightTexture::LightTexture(const char *name, const LightTextureManager *mgr) field_0x9C = 0; mpFloatData = new float[mNumData]; mpByteData1 = new char[mNumData]; - mpByteData2 = new char[mNumData]; + mpByteData2 = new u8[mNumData]; for (int i = 0; i < mNumData; i++) { mpByteData2[i] = 0; mpFloatData[i] = 1.0f; @@ -148,6 +158,161 @@ void LightTexture::configure() { setPixModeSync(false); } +void LightTexture::loadTextureData(int index, void *data, GXTexFmt fmt) { + CpuTexture *pTex = sCpuTexArray[index]; + CpuTexture tmpTex(64, 4, fmt); + tmpTex.configure(); + tmpTex.setBuffer(data); + for (u32 y = 0; y < 4; y++) { + for (int x = 0; x < 32; x++) { + pTex->setColor(x, y, tmpTex.getColor(x + 32, y)); + } + for (int x = 0; x < 32; x++) { + pTex->setColor(x + 32, y, tmpTex.getColor(x, y)); + } + } + pTex->flush(); +} + +void LightTexture::loadTextureFromResTimg(int index, EGG::ResTIMG *img) { + loadTextureData(index, img + 1, static_cast(img->format)); +} + +void LightTexture::initDrawSetting(u16 u1, u16 u2, u16 u3, u16 u4) { + static const u8 sVtxBuf[] = {0, 0, 0, 1, 1, 1, 1, 0}; + + nw4r::math::MTX44 mtx; + C_MTXOrtho(mtx, u4, 0.0f, 0.0f, u3, 0.0f, 1.0f); + StateGX::GXSetProjection_(mtx, GX_ORTHOGRAPHIC); + StateGX::GXSetViewport_(u1, u2, u3, u4, 0.0f, 1.0f); + StateGX::GXSetScissor_(u1, u2, u3, u4); + StateGX::GXSetScissorBoxOffset_(0, 0); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetArray(GX_VA_POS, sVtxBuf, 2); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGB565, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_F32, 0); + + sTexWidth = sTextureSize; + sDrawNumX = u3 / sTextureSize; + sTexHeight = sTextureSize; + sDrawNumY = u4 / sTextureSize; + sDrawWidth = u3; + sDrawHeight = u4; + sDrawPosX = u1; + sDrawPosY = u2; + + fn_804AB270(); + GXSetCurrentMtx(0); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); +} + +void LightTexture::draw(int i) {} + +void LightTexture::beginDebugDraw() { + DrawGX::SetMat_ColorChannel(DrawGX::COLORCHAN_1); + DrawGX::SetMat_TexGen(DrawGX::TEXGEN_1); + DrawGX::SetMat_Ind(); + DrawGX::SetMat_PE(DrawGX::ZMODE_0, DrawGX::BLEND_14); + GXSetNumTevStages(1); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); +} + +void LightTexture::debugDraw(int i) { + StateGX::ScopedDither ditherGuard(false); + field_0x9F = 0; + int u1, u2; + fn_804AC0A0(i, &u1, &u2); + load(GX_TEXMAP0); + nw4r::math::MTX34 mtx; + PSMTXScale(mtx, sTexWidth, sTexHeight, 1.0f); + + mtx._03 = u1; + mtx._13 = sDrawHeight - (u2 + sTexHeight); + + GXLoadPosMtxImm(mtx, 0); + GXLoadTexMtxImm(sMtx, 0x1E, GX_MTX_2x4); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + + GXPosition1x8(0); + GXPosition2f32(0.0f, 1.0f); + + GXPosition1x8(1); + GXPosition2f32(0.0f, 0.0f); + + GXPosition1x8(2); + GXPosition2f32(1.0f, 0.0f); + + GXPosition1x8(3); + GXPosition2f32(1.0f, 1.0f); +} + +void LightTexture::addLight(const EGG::LightObject &obj) { + // NONMATCHING + if (!(obj.CheckFlag1() && obj.CheckFlag0x20() && (mpByteData1[obj.GetIndex()] & 1) != 0 && + (field_0x9F < 2 || mLightType != 1))) { + return; + } + + nw4r::math::VEC3 vec; + GXColor color; + obj.fn_804A9C30(this, &vec, &color); + int remainder = field_0x9F % field_0x9D; + if (field_0x9F == field_0x9D) { + GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + } + sCpuTexArray[mpByteData2[obj.GetIndex()]]->load(static_cast(field_0x9E + remainder)); + + // TODO + GXColor blackColor = obj.GetBlack(); + // Sorry clang-format, what is this formatting??? + blackColor = (GXColor + ){blackColor.r * obj.getField0x30(), blackColor.g * obj.getField0x30(), blackColor.b * obj.getField0x30(), + blackColor.a}; + GXSetTevColor(static_cast(GX_TEVREG0 + remainder), color); + GXSetTevKColor(static_cast(GX_KCOLOR0 + remainder), blackColor); + if (GetLightType() == 0 || GetLightType() == 2) { + f32 mtx[2][3]; + mtx[0][0] = -vec.x * 0.485f; + mtx[0][1] = -vec.y * 0.485f; + mtx[0][2] = -vec.z * 0.485f; + mtx[1][0] = 0.0f; + mtx[1][1] = 0.0f; + mtx[1][2] = 0.0f; + + static const GXIndTexMtxID sIds[] = {GX_ITM_0, GX_ITM_1, GX_ITM_2}; + + GXSetIndTexMtx(sIds[remainder], mtx, -1); + } + + if (remainder == field_0x9D - 1) { + f32 v = GetLightType() != 2 ? 0.0f : 0.5f; + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + + GXPosition1x8(0); + GXPosition2f32(v, v); + + GXPosition1x8(1); + GXPosition2f32(v, v - 0.99f); + + GXPosition1x8(2); + GXPosition2f32(v + 0.99f, v - 0.99f); + + GXPosition1x8(3); + GXPosition2f32(v + 0.99f, v); + } + + field_0x9F++; +} + void LightTexture::SetBinaryInner(const Bin &bin) { // Not bothering with version differences right now, // since the game uses V3 and GetBinaryInner is enough From 811e7746780f14a4d26e351d592c79b52072e4df Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 27 Mar 2025 15:41:44 +0100 Subject: [PATCH 44/62] LightTexture close --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 16 +- include/egg/gfx/eggLightManager.h | 6 +- include/egg/gfx/eggLightTexture.h | 9 + include/egg/gfx/eggLightTextureMgr.h | 27 +++ src/egg/gfx/eggLightTexture.cpp | 303 +++++++++++++++++++++++++-- 6 files changed, 341 insertions(+), 21 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 84c47baf..6b35f7f4 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2272,6 +2272,7 @@ egg/gfx/eggLightTexture.cpp: .rodata start:0x804FBC98 end:0x804FBD08 .data start:0x8056F0B8 end:0x8056F0F0 .sdata start:0x80574F38 end:0x80574F48 + .sbss start:0x80576848 end:0x80576860 .sdata2 start:0x8057F6C0 end:0x8057F708 .bss start:0x80674E78 end:0x80674EF0 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 45bb9ebe..35c7493f 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26635,10 +26635,10 @@ GetBinaryInner__Q23EGG11LightObjectCFPQ33EGG28IBinary3Bin = SetBinaryInner__Q23EGG11LightObjectFRCQ33EGG28IBinary3BinRCQ33EGG28IBinary3Binf = .text:0x804AAC60; // type:function size:0x5EC GetBinaryType__Q23EGG29IBinaryFv = .text:0x804AB250; // type:function size:0x8 GetVersion__Q23EGG29IBinaryFv = .text:0x804AB260; // type:function size:0x8 -FUN_804ab270 = .text:0x804AB270; // type:function size:0x9C -FUN_804ab310 = .text:0x804AB310; // type:function size:0x124 -FUN_804ab440 = .text:0x804AB440; // type:function size:0x1B4 -FUN_804ab600 = .text:0x804AB600; // type:function size:0x180 +fn_804AB270__Q23EGG12LightTextureFv = .text:0x804AB270; // type:function size:0x9C +fn_804AB310__Q23EGG12LightTextureFRC8_GXColor = .text:0x804AB310; // type:function size:0x124 +fn_804AB440__Q23EGG12LightTextureFv = .text:0x804AB440; // type:function size:0x1B4 +fn_804AB600__Q23EGG12LightTextureFv = .text:0x804AB600; // type:function size:0x180 initialize__Q23EGG12LightTextureFUsPQ23EGG4Heap = .text:0x804AB780; // type:function size:0x26C __ct__Q23EGG12LightTextureFPCcPCQ23EGG19LightTextureManager = .text:0x804AB9F0; // type:function size:0x284 __dt__Q23EGG12LightTextureFv = .text:0x804ABC80; // type:function size:0x90 @@ -26646,9 +26646,9 @@ configure__Q23EGG12LightTextureFv = .text:0x804ABD10; // type:function size:0x6C loadTextureData__Q23EGG12LightTextureFiPv9_GXTexFmt = .text:0x804ABD80; // type:function size:0x10C loadTextureFromResTimg__Q23EGG12LightTextureFiPQ23EGG7ResTIMG = .text:0x804ABE90; // type:function size:0xC initDrawSetting__Q23EGG12LightTextureFUsUsUsUs = .text:0x804ABEA0; // type:function size:0x1A4 -FUN_804ac050 = .text:0x804AC050; // type:function size:0x4C -FUN_804ac0a0 = .text:0x804AC0A0; // type:function size:0x34 -FUN_804ac0e0 = .text:0x804AC0E0; // type:function size:0x490 +getTexDimensions__Q23EGG12LightTextureFPUsPUsPUsPUsUs = .text:0x804AC050; // type:function size:0x4C +fn_804AC0A0__Q23EGG12LightTextureFiPiPi = .text:0x804AC0A0; // type:function size:0x34 +fn_804AC0E0__Q23EGG12LightTextureFiRC8_GXColorb = .text:0x804AC0E0; // type:function size:0x490 draw__Q23EGG12LightTextureFi = .text:0x804AC570; // type:function size:0x3E8 beginDebugDraw__Q23EGG12LightTextureFv = .text:0x804AC960; // type:function size:0xD8 debugDraw__Q23EGG12LightTextureFi = .text:0x804ACA40; // type:function size:0x18C @@ -41168,7 +41168,7 @@ sTexHeight__Q23EGG12LightTexture = .sbss:0x80576852; // type:object size:0x2 dat sDrawNumX__Q23EGG12LightTexture = .sbss:0x80576854; // type:object size:0x2 data:2byte sDrawNumY__Q23EGG12LightTexture = .sbss:0x80576856; // type:object size:0x2 data:2byte spNormalEnvironment__Q23EGG12LightTexture = .sbss:0x80576858; // type:object size:0x4 data:4byte -lbl_8057685C = .sbss:0x8057685C; // type:object size:0x1 data:byte +sUseDebug__Q23EGG12LightTexture = .sbss:0x8057685C; // type:object size:0x1 data:byte lbl_80576860 = .sbss:0x80576860; // type:object size:0x1 data:byte lbl_80576861 = .sbss:0x80576861; // type:object size:0x7 data:byte lbl_80576868 = .sbss:0x80576868; // type:object size:0x8 data:float diff --git a/include/egg/gfx/eggLightManager.h b/include/egg/gfx/eggLightManager.h index c715dcef..b684bd06 100644 --- a/include/egg/gfx/eggLightManager.h +++ b/include/egg/gfx/eggLightManager.h @@ -27,13 +27,13 @@ class LightManager : public IBinary { }; }; +public: struct AmbientObject { /* 0x00 */ nw4r::g3d::AmbLightObj mLightObj; /* 0x04 */ const char *mLightName; /* 0x08 */ u8 field_0x08; }; -public: struct BinAmbient { /* 0x00 */ u8 field_0x00; /* 0x01 */ u8 field_0x01; @@ -93,6 +93,10 @@ public: return &mpLightData[i].mLightObject; } + const AmbientObject *GetAmbientObject(int i) const { + return &mpAmbientObjects[i]; + } + /* 0x04 */ Counts mCounts; /* 0x06 */ Counts mSavedCounts; /* 0x08 */ LightData *mpLightData; diff --git a/include/egg/gfx/eggLightTexture.h b/include/egg/gfx/eggLightTexture.h index bb52ed78..419f6d44 100644 --- a/include/egg/gfx/eggLightTexture.h +++ b/include/egg/gfx/eggLightTexture.h @@ -56,6 +56,7 @@ public: static void initDrawSetting(u16, u16, u16, u16); void addLight(const EGG::LightObject&); + void fn_804AC0E0(int, const GXColor&, bool); void draw(int); void beginDebugDraw(); void debugDraw(int); @@ -72,6 +73,11 @@ public: private: static void fn_804AB270(); + static void fn_804AB310(const GXColor &color); + static void fn_804AB440(); + static void fn_804AB600(); + + static void getTexDimensions(u16*, u16*, u16*, u16*, u16); static void fn_804AC0A0(int, int*, int*); static void loadTextureData(int index, void *data, GXTexFmt fmt); @@ -118,6 +124,9 @@ private: static u16 sDrawNumX; static u16 sDrawNumY; static CpuTexture *spNormalEnvironment; + + // unsure + static bool sUseDebug; }; } // namespace EGG diff --git a/include/egg/gfx/eggLightTextureMgr.h b/include/egg/gfx/eggLightTextureMgr.h index 4225e0db..0ce4f1f2 100644 --- a/include/egg/gfx/eggLightTextureMgr.h +++ b/include/egg/gfx/eggLightTextureMgr.h @@ -1,7 +1,9 @@ #ifndef EGG_LIGHT_TEXTURE_MGR_H #define EGG_LIGHT_TEXTURE_MGR_H +#include "common.h" #include "egg/gfx/eggLightTexture.h" +#include "egg/gfx/eggLightManager.h" #include "egg/prim/eggBinary.h" #include "nw4r/g3d/res/g3d_resmdl.h" @@ -45,7 +47,32 @@ public: return mTextureCount; } + LightTexture *getTextureByName(const char *name) const { + int idx = getTextureIndex(name); + if (idx != -1) { + return mpTextures[idx]; + } else { + return nullptr; + } + } + + const nw4r::g3d::AmbLightObj &GetAmbientObj(int idx) const { + return mpLightMgr->GetAmbientObject(idx)->mLightObj; + } + + const LightObject *GetLightObject(u16 i) const { + return mpObjects[i]; + } + + LightObject *GetLightObject(u16 i) { + return mpObjects[i]; + } + + private: + + int getTextureIndex(const char *name) const; + /* 0x04 */ u8 field_0x04; /* 0x06 */ u16 mTextureCount; /* 0x08 */ LightTexture **mpTextures; diff --git a/src/egg/gfx/eggLightTexture.cpp b/src/egg/gfx/eggLightTexture.cpp index b4827998..d6d4f32d 100644 --- a/src/egg/gfx/eggLightTexture.cpp +++ b/src/egg/gfx/eggLightTexture.cpp @@ -8,6 +8,7 @@ #include "egg/gfx/eggLightObject.h" #include "egg/gfx/eggLightTextureMgr.h" #include "egg/gfx/eggStateGX.h" +#include "nw4r/g3d/g3d_light.h" #include "nw4r/math/math_types.h" #include "rvl/GX/GXBump.h" #include "rvl/GX/GXGeometry.h" @@ -25,12 +26,21 @@ namespace EGG { #define NUM_CPU_TEX 18 static CpuTexture *sCpuTexArray[NUM_CPU_TEX]; -static const int sCpuTexGradientOp[NUM_CPU_TEX] = {0, 0, 0, 1, 2, 3, 4, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0}; -static nw4r::math::MTX34 sMtx(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); +u16 LightTexture::sDrawWidth; +u16 LightTexture::sDrawHeight; +u16 LightTexture::sDrawPosX; +u16 LightTexture::sDrawPosY; +u16 LightTexture::sTexWidth; +u16 LightTexture::sTexHeight; +u16 LightTexture::sDrawNumX; +u16 LightTexture::sDrawNumY; + +CpuTexture *LightTexture::spNormalEnvironment; + +bool LightTexture::sUseDebug; u16 LightTexture::sTextureSize = 0x20; -CpuTexture *LightTexture::spNormalEnvironment; static s8 lbl_80574F3A = 0xFE; @@ -44,7 +54,94 @@ int IBinary::GetVersion() { return 3; } +void LightTexture::fn_804AB270() { + GXSetNumChans(1); + GXSetCullMode(GX_CULL_BACK); + GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_SIGN, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1A1, false, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + GXSetZMode(false, GX_LEQUAL, false); + EGG::DrawGX::SetBlendMode(DrawGX::BLEND_14); +} + +void LightTexture::fn_804AB310(const GXColor &color) { + GXSetNumTexGens(0); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetNumIndStages(0); + GXSetNumTevStages(1); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevKColor(GX_KCOLOR0, color); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_1); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_KONST); + 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_KONST); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + EGG::DrawGX::SetBlendMode(DrawGX::BLEND_14); +} + +static const GXTevColorArg sTevkColorArg[3] = {GX_CC_C0, GX_CC_C1, GX_CC_C2}; +static const GXTevKColorSel sTevkColorSel[3] = {GX_TEV_KCSEL_K0, GX_TEV_KCSEL_K1, GX_TEV_KCSEL_K2}; +static const GXIndTexMtxID sIndTexMtxId[3] = {GX_ITM_0, GX_ITM_1, GX_ITM_2}; + +void LightTexture::fn_804AB440() { + GXSetNumTexGens(1); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetNumIndStages(1); + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP0); + GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); + GXSetNumTevStages(3); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + + for (int i = 0; i < 3; i++) { + GXTevStageID id = static_cast(GX_TEVSTAGE0 + i); + GXTevColorArg tevColorArg = id == GX_TEVSTAGE0 ? GX_CC_ZERO : GX_CC_CPREV; + + GXSetTevSwapMode(id, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(id, GX_TEXCOORD_NULL, static_cast(GX_TEXMAP1 + i), GX_COLOR_NULL); + GXSetTevKColorSel(id, sTevkColorSel[i]); + GXSetTevKAlphaSel(id, GX_TEV_KASEL_1); + GXSetTevColorIn(id, GX_CC_KONST, sTevkColorArg[i], GX_CC_TEXC, tevColorArg); + GXSetTevColorOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + GXSetTevAlphaOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevIndirect( + id, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_STU, sIndTexMtxId[i], GX_ITW_0, GX_ITW_0, false, false, GX_ITBA_OFF + ); + } + EGG::DrawGX::SetBlendMode(DrawGX::BLEND_2); +} + +void LightTexture::fn_804AB600() { + GXSetNumTexGens(2); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, 0x1e, 0, 0x7d); + GXSetNumIndStages(0); + GXSetNumTevStages(2); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + for (int i = 0; i < 2; i++) { + GXTevStageID id = static_cast(GX_TEVSTAGE0 + i); + GXTevColorArg tevColorArg = id == GX_TEVSTAGE0 ? GX_CC_ZERO : GX_CC_CPREV; + + GXSetTevOrder( + id, static_cast(GX_TEXCOORD0 + i), static_cast(GX_TEXMAP0 + i), GX_COLOR_NULL + ); + GXSetTevKColorSel(id, sTevkColorSel[i]); + GXSetTevKAlphaSel(id, GX_TEV_KASEL_1); + GXSetTevColorIn(id, GX_CC_KONST, sTevkColorArg[i], GX_CC_TEXC, tevColorArg); + GXSetTevColorOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(id, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + GXSetTevAlphaOp(id, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevDirect(id); + } + EGG::DrawGX::SetBlendMode(DrawGX::BLEND_2); +} + void LightTexture::initialize(u16 textureSize, Heap *pHeap) { + static const int sCpuTexGradientOp[NUM_CPU_TEX] = {0, 0, 0, 1, 2, 3, 4, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0}; + if (pHeap == nullptr) { pHeap = Heap::getCurrentHeap(); } @@ -145,11 +242,9 @@ LightTexture::~LightTexture() { delete[] mpByteData2; } -extern "C" bool lbl_8057685C; - void LightTexture::configure() { CapTexture::configure(); - if (lbl_8057685C) { + if (sUseDebug) { allocWithHeaderDebug(nullptr); } else { allocate(nullptr); @@ -179,7 +274,7 @@ void LightTexture::loadTextureFromResTimg(int index, EGG::ResTIMG *img) { } void LightTexture::initDrawSetting(u16 u1, u16 u2, u16 u3, u16 u4) { - static const u8 sVtxBuf[] = {0, 0, 0, 1, 1, 1, 1, 0}; + static const u8 ALIGN_DECL(32) sVtxBuf[] = {0, 0, 0, 1, 1, 1, 1, 0}; nw4r::math::MTX44 mtx; C_MTXOrtho(mtx, u4, 0.0f, 0.0f, u3, 0.0f, 1.0f); @@ -208,7 +303,193 @@ void LightTexture::initDrawSetting(u16 u1, u16 u2, u16 u3, u16 u4) { GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); } -void LightTexture::draw(int i) {} +void LightTexture::getTexDimensions(u16 *x, u16 *y, u16 *w, u16 *h, u16 count) { + *x = sDrawPosX; + *y = sDrawPosY; + + u16 s1 = count / (sDrawNumX + 1); + u16 wp = (count - s1 * sDrawNumX); + *w = wp * sTexWidth; + *h = (s1 + 1) * sTexHeight; +} + +void LightTexture::fn_804AC0A0(int i, int *x, int *y) { + *y = i / sDrawNumX; + *x = sTexWidth * (i % sDrawNumX); + *y *= sTexHeight; +} + +static const nw4r::math::MTX34 sIdentityMtx(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); + +void LightTexture::fn_804AC0E0(int i, const GXColor &color, bool b) { + field_0x9F = 0; + field_0x9C = 1; + int w, h; + fn_804AC0A0(i, &w, &h); + + nw4r::math::MTX34 mtx = sIdentityMtx; + mtx._00 *= sTexWidth; + mtx._11 *= sTexHeight; + mtx._03 = w; + mtx._13 = sDrawHeight - (h + sTexHeight); + + GXLoadPosMtxImm(mtx, 0); + GXLoadTexMtxImm(sIdentityMtx, 0x1E, GX_MTX_2x4); + + GXColor c; + if ((field_0x36 & 1) != 0) { + const nw4r::g3d::AmbLightObj &obj = mpMgr->GetAmbientObj(field_0x35); + c.r = obj.r; + c.g = obj.g; + c.b = obj.b; + c.a = obj.a; + + c.r = c.r * field_0x50; + c.g = c.g * field_0x50; + c.b = c.b * field_0x50; + c.a = 0xFF; + } else { + c = DrawGX::BLACK; + } + + fn_804AB310(c); + + f32 origin = 0.0f; + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + f32 d = 0.99f; + + GXPosition1x8(0); + GXPosition2f32(origin, origin); + + GXPosition1x8(1); + GXPosition2f32(origin, origin - d); + + GXPosition1x8(2); + GXPosition2f32(d + origin, origin - d); + + GXPosition1x8(3); + GXPosition2f32(d + origin, origin); + + switch (mLightType) { + case 0: + case 2: + spNormalEnvironment->load(GX_TEXMAP0); + fn_804AB440(); + field_0x9D = 3; + field_0x9E = 1; + break; + + case 1: + fn_804AB600(); + field_0x9D = 2; + field_0x9E = 0; + break; + } + + for (int i = 0; i < mpMgr->getMaxNumLightTextures(); i++) { + if (mpMgr->GetLightObject(i) == nullptr) { + break; + } + addLight(*mpMgr->GetLightObject(i)); + } + + int remainder = field_0x9F % field_0x9D; + if (remainder > 0) { + for (; remainder < field_0x9D; remainder++) { + // TODO: color stack slots swapped + GXSetTevColor(static_cast(GX_TEVREG0 + remainder), DrawGX::BLACK); + GXSetTevKColor(static_cast(GX_KCOLOR0 + remainder), DrawGX::BLACK); + } + + f32 origin = GetLightType() != 2 ? 0.0f : 0.5f; + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + f32 d = 0.99f; + GXPosition1x8(0); + GXPosition2f32(origin, origin); + + GXPosition1x8(1); + GXPosition2f32(origin, origin - d); + + GXPosition1x8(2); + GXPosition2f32(d + origin, origin - d); + + GXPosition1x8(3); + GXPosition2f32(d + origin, origin); + } + + field_0x9C = 2; + if (b) { + onCapFlag(1); + onCapFlag(2); + setClearColor(color); + } else { + offCapFlag(1); + offCapFlag(2); + } + capture(sDrawPosX + w, sDrawPosY + h, false, -1); + field_0x9C = 0; +} + +void LightTexture::draw(int i) { + if ((field_0x36 & 2) == 0) { + return; + } + + LightTexture *other = mpMgr->getTextureByName(mName2); + if (other == nullptr) { + return; + } + field_0x9F = 0; + int w, h; + fn_804AC0A0(i, &w, &h); + load(GX_TEXMAP0); + other->load(GX_TEXMAP1); + DrawGX::SetMat_ColorChannel(DrawGX::COLORCHAN_1); + DrawGX::SetMat_TexGen(DrawGX::TEXGEN_1); + DrawGX::SetMat_Ind(); + DrawGX::SetMat_PE(DrawGX::ZMODE_0, DrawGX::BLEND_14); + GXSetNumTevStages(2); + u8 val = field_0x98 * 255.0f; + GXSetTevColor(GX_TEVREG0, (GXColor){val, val, val, val}); + GXSetTevDirect(GX_TEVSTAGE0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ONE, GX_CC_TEXC, GX_CC_C0, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevDirect(GX_TEVSTAGE1); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXC, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + + nw4r::math::MTX34 mtx = sIdentityMtx; + mtx._00 *= sTexWidth; + mtx._11 *= sTexHeight; + mtx._03 = w; + mtx._13 = sDrawHeight - (h + sTexHeight); + + GXLoadPosMtxImm(mtx, 0); + GXLoadTexMtxImm(sIdentityMtx, 0x1E, GX_MTX_2x4); + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + + GXPosition1x8(0); + GXPosition2f32(0.0f, 1.0f); + + GXPosition1x8(1); + GXPosition2f32(0.0f, 0.0f); + + GXPosition1x8(2); + GXPosition2f32(1.0f, 0.0f); + + GXPosition1x8(3); + GXPosition2f32(1.0f, 1.0f); + + capture(sDrawPosX + w, sDrawPosY + h, false, -1); +} void LightTexture::beginDebugDraw() { DrawGX::SetMat_ColorChannel(DrawGX::COLORCHAN_1); @@ -238,7 +519,7 @@ void LightTexture::debugDraw(int i) { mtx._13 = sDrawHeight - (u2 + sTexHeight); GXLoadPosMtxImm(mtx, 0); - GXLoadTexMtxImm(sMtx, 0x1E, GX_MTX_2x4); + GXLoadTexMtxImm(sIdentityMtx, 0x1E, GX_MTX_2x4); GXBegin(GX_QUADS, GX_VTXFMT0, 4); @@ -288,9 +569,7 @@ void LightTexture::addLight(const EGG::LightObject &obj) { mtx[1][1] = 0.0f; mtx[1][2] = 0.0f; - static const GXIndTexMtxID sIds[] = {GX_ITM_0, GX_ITM_1, GX_ITM_2}; - - GXSetIndTexMtx(sIds[remainder], mtx, -1); + GXSetIndTexMtx(sIndTexMtxId[remainder], mtx, -1); } if (remainder == field_0x9D - 1) { From e8d9aae33e779f6aee484eedc7d1a1df8307edb5 Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 27 Mar 2025 15:51:45 +0100 Subject: [PATCH 45/62] Minor fixes --- config/SOUE01/splits.txt | 1 + src/egg/gfx/eggCpuTexture.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 6b35f7f4..021f9266 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2264,6 +2264,7 @@ egg/gfx/eggLightObject.cpp: .text start:0x804A9810 end:0x804AB24C .rodata start:0x804FBC88 end:0x804FBC98 .data start:0x8056F098 end:0x8056F0B8 + .sdata start:0x80574F30 end:0x80574F38 .sdata2 start:0x8057F690 end:0x8057F6C0 egg/gfx/eggLightTexture.cpp: diff --git a/src/egg/gfx/eggCpuTexture.cpp b/src/egg/gfx/eggCpuTexture.cpp index f5b925c9..955641a4 100644 --- a/src/egg/gfx/eggCpuTexture.cpp +++ b/src/egg/gfx/eggCpuTexture.cpp @@ -290,7 +290,7 @@ void CpuTexture::setColor(u16 x, u16 y, GXColor color) { case GX_TF_I8: case GX_TF_Z8: { // TODO - int offset = ((x >> 3) + (y >> 2) * (getWidth() / 8)) * 0x20 + (x & 3) * 8 + (x & 7); + int offset = ((x >> 3) + (y >> 2) * (getWidth() / 8)) * 0x20 + (y & 3) * 8 + (x & 7); u8 *dat = static_cast(getBuffer()) + offset; dat[0] = color.r; break; @@ -325,7 +325,7 @@ GXColor CpuTexture::getColor(u16 x, u16 y) const { case GX_TF_I8: case GX_TF_Z8: { // TODO - int offset = ((x >> 3) + (y >> 2) * (getWidth() / 8)) * 0x20 + (x & 3) * 8 + (x & 7); + int offset = ((x >> 3) + (y >> 2) * (getWidth() / 8)) * 0x20 + (y & 3) * 8 + (x & 7); u8 *dat = static_cast(getBuffer()) + offset; c.a = dat[0]; c.b = dat[0]; From 64528b423f2a9ffe3b3982c39eb16c7cd962b3dd Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 27 Mar 2025 17:52:09 +0100 Subject: [PATCH 46/62] LightTextureManager OK --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 8 +- configure.py | 2 +- include/egg/gfx/eggG3DUtility.h | 14 ++- include/egg/gfx/eggLightManager.h | 13 ++- include/egg/gfx/eggLightTexture.h | 4 +- include/egg/gfx/eggLightTextureMgr.h | 19 +-- src/egg/gfx/eggLightTextureMgr.cpp | 165 +++++++++++++++++++++++++-- 8 files changed, 198 insertions(+), 28 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 021f9266..a23f47c7 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2280,6 +2280,7 @@ egg/gfx/eggLightTexture.cpp: egg/gfx/eggLightTextureMgr.cpp: .text start:0x804AD450 end:0x804AE644 .data start:0x8056F0F0 end:0x8056F110 + .sdata2 start:0x8057F708 end:0x8057F720 egg/gfx/eggModelEx.cpp: .text start:0x804AE650 end:0x804AEC20 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 35c7493f..3cb741c6 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26567,7 +26567,7 @@ setUpLightSet__Q23EGG10G3DUtilityFRQ34nw4r3g3d12LightSettingQ34nw4r3g3d9ResAnmSc FUN_804a6ba0 = .text:0x804A6BA0; // type:function size:0x104 FUN_804a6cb0 = .text:0x804A6CB0; // type:function size:0x104 FUN_804a6dc0 = .text:0x804A6DC0; // type:function size:0x144 -SetTexture = .text:0x804A6F10; // type:function size:0x350 +SetTexture__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMatPQ44nw4r3g3d6ScnMdl15CopiedMatAccessPCcP9_GXTexObjbPQ33EGG10G3DUtility16SetTextureResultii = .text:0x804A6F10; // type:function size:0x350 FUN_804a7260 = .text:0x804A7260; // type:function size:0x31C FUN_804a7580 = .text:0x804A7580; // type:function size:0x30 __dt__Q33EGG9GfxEngine13ConfigurationFv = .text:0x804A75B0; // type:function size:0x40 @@ -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__Q23EGG19LightTextureManagerCFUsQ34nw4r3g3d6ResMdl = .text:0x804AD990; // type:function size:0x104 +replaceModelTexture__Q23EGG19LightTextureManagerCFiQ34nw4r3g3d6ResMdl = .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 @@ -26678,7 +26678,7 @@ drawAndCaptureTexture__Q23EGG19LightTextureManagerFffff = .text:0x804ADC80; // t SetBinaryInner__Q23EGG19LightTextureManagerFRCQ33EGG36IBinary3Bin = .text:0x804AE150; // type:function size:0x80 GetBinaryInner__Q23EGG19LightTextureManagerCFPQ33EGG36IBinary3Bin = .text:0x804AE1D0; // type:function size:0x90 getLtexFromLmap__Q23EGG19LightTextureManagerFPCvUs = .text:0x804AE260; // type:function size:0xDC -FUN_804ae340 = .text:0x804AE340; // type:function size:0xBC +fn_804AE340__Q23EGG19LightTextureManagerFQ34nw4r3g3d6ResMat13_GXTexCoordID = .text:0x804AE340; // type:function size:0xBC GetBinarySize__Q23EGG19LightTextureManagerCFv = .text:0x804AE400; // type:function size:0x8 SetBinaryInner__Q23EGG36IBinaryFRCQ33EGG36IBinary3BinRCQ33EGG36IBinary3Binf = .text:0x804AE410; // type:function size:0x4 SetBinary__Q23EGG29IBinaryFPCv = .text:0x804AE420; // type:function size:0x10 @@ -41170,7 +41170,7 @@ sDrawNumY__Q23EGG12LightTexture = .sbss:0x80576856; // type:object size:0x2 data spNormalEnvironment__Q23EGG12LightTexture = .sbss:0x80576858; // type:object size:0x4 data:4byte sUseDebug__Q23EGG12LightTexture = .sbss:0x8057685C; // type:object size:0x1 data:byte lbl_80576860 = .sbss:0x80576860; // type:object size:0x1 data:byte -lbl_80576861 = .sbss:0x80576861; // type:object size:0x7 data:byte +lbl_80576861 = .sbss:0x80576861; // type:object size:0x1 data:byte lbl_80576868 = .sbss:0x80576868; // type:object size:0x8 data:float sTVMode__Q23EGG6Screen = .sbss:0x80576870; // type:object size:0x4 data:4byte spRoot__Q23EGG6Screen = .sbss:0x80576874; // type:object size:0x4 data:4byte diff --git a/configure.py b/configure.py index 0fe32e28..cb7cacf2 100644 --- a/configure.py +++ b/configure.py @@ -887,7 +887,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggLightManager.cpp"), Object(NonMatching, "egg/gfx/eggLightObject.cpp"), Object(NonMatching, "egg/gfx/eggLightTexture.cpp"), - Object(NonMatching, "egg/gfx/eggLightTextureMgr.cpp"), + Object(Matching, "egg/gfx/eggLightTextureMgr.cpp"), Object(NonMatching, "egg/gfx/eggModelEx.cpp"), Object(Matching, "egg/gfx/eggPostEffectBase.cpp"), Object(Matching, "egg/gfx/eggPostEffectBlur.cpp"), diff --git a/include/egg/gfx/eggG3DUtility.h b/include/egg/gfx/eggG3DUtility.h index bb26c177..15250313 100644 --- a/include/egg/gfx/eggG3DUtility.h +++ b/include/egg/gfx/eggG3DUtility.h @@ -13,12 +13,18 @@ public: return sAllocator; } - static u16 SetTexture( - nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess param_2, char *name, GXTexObj *texObj, bool copy, - void *param_6, int param_7, int param_8 + struct SetTextureResult { + /* 0x00 */ u8 _0x00[2]; + /* 0x02 */ s8 texMapId; + /* 0x03 */ s8 texCoordId; + }; + + static u32 SetTexture( + nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *param_2, const char *name, GXTexObj *texObj, bool copy, + SetTextureResult *pResult, int param_7, int param_8 ); - static void setUpLightSet(nw4r::g3d::LightSetting&, nw4r::g3d::ResAnmScn, int); + static void setUpLightSet(nw4r::g3d::LightSetting &, nw4r::g3d::ResAnmScn, int); private: static MEMAllocator *sAllocator; diff --git a/include/egg/gfx/eggLightManager.h b/include/egg/gfx/eggLightManager.h index b684bd06..c863cdc4 100644 --- a/include/egg/gfx/eggLightManager.h +++ b/include/egg/gfx/eggLightManager.h @@ -85,11 +85,11 @@ public: return num < 8 ? num : 8; } - const LightObject *GetLightObject(int i) const { + const LightObject *GetLightObject(u16 i) const { return &mpLightData[i].mLightObject; } - LightObject *GetLightObject(int i) { + LightObject *GetLightObject(u16 i) { return &mpLightData[i].mLightObject; } @@ -97,6 +97,15 @@ public: return &mpAmbientObjects[i]; } + u8 GetNumLightData() const { + return mCounts.mNumEggLightObjects; + } + + u8 GetField0x1D() const { + return field_0x1D; + } + +private: /* 0x04 */ Counts mCounts; /* 0x06 */ Counts mSavedCounts; /* 0x08 */ LightData *mpLightData; diff --git a/include/egg/gfx/eggLightTexture.h b/include/egg/gfx/eggLightTexture.h index 419f6d44..c79db857 100644 --- a/include/egg/gfx/eggLightTexture.h +++ b/include/egg/gfx/eggLightTexture.h @@ -58,7 +58,7 @@ public: void fn_804AC0E0(int, const GXColor&, bool); void draw(int); - void beginDebugDraw(); + static void beginDebugDraw(); void debugDraw(int); const char *getName() const { @@ -69,6 +69,7 @@ public: return mpFloatData[idx]; } + static void getTexDimensions(u16*, u16*, u16*, u16*, u16); private: @@ -77,7 +78,6 @@ private: static void fn_804AB440(); static void fn_804AB600(); - static void getTexDimensions(u16*, u16*, u16*, u16*, u16); static void fn_804AC0A0(int, int*, int*); static void loadTextureData(int index, void *data, GXTexFmt fmt); diff --git a/include/egg/gfx/eggLightTextureMgr.h b/include/egg/gfx/eggLightTextureMgr.h index 0ce4f1f2..86400aa1 100644 --- a/include/egg/gfx/eggLightTextureMgr.h +++ b/include/egg/gfx/eggLightTextureMgr.h @@ -2,9 +2,10 @@ #define EGG_LIGHT_TEXTURE_MGR_H #include "common.h" -#include "egg/gfx/eggLightTexture.h" #include "egg/gfx/eggLightManager.h" +#include "egg/gfx/eggLightTexture.h" #include "egg/prim/eggBinary.h" +#include "nw4r/g3d/res/g3d_resmat.h" #include "nw4r/g3d/res/g3d_resmdl.h" namespace EGG { @@ -30,9 +31,10 @@ public: bool deleteTexture(int idx); int replaceModelTextures(nw4r::g3d::ResMdl) const; - int replaceModelTexture(u16, nw4r::g3d::ResMdl) const; + int replaceModelTexture(int, nw4r::g3d::ResMdl) const; void drawAndCaptureTexture(f32, f32, f32, f32); void frameReset(); + void correctLightObject(); // Inofficial static const void *getLtexFromLmap(const void *lmap, u16 index); @@ -64,23 +66,26 @@ public: return mpObjects[i]; } - LightObject *GetLightObject(u16 i) { + const LightObject *GetLightObject(u16 i) { return mpObjects[i]; } - private: - + static void fn_804AE340(nw4r::g3d::ResMat, GXTexCoordID); int getTextureIndex(const char *name) const; - /* 0x04 */ u8 field_0x04; + bool getSomeTfRelatedBool() const { + return (mFlags >> 5) & 1; + } + + /* 0x04 */ u8 mFlags; /* 0x06 */ u16 mTextureCount; /* 0x08 */ LightTexture **mpTextures; /* 0x0C */ const LightManager *mpLightMgr; /* 0x10 */ u32 field_0x10; /* 0x14 */ u16 mMaxNumTextures; /* 0x16 */ u8 field_0x16; - /* 0x18 */ LightObject **mpObjects; + /* 0x18 */ const LightObject **mpObjects; }; } // namespace EGG diff --git a/src/egg/gfx/eggLightTextureMgr.cpp b/src/egg/gfx/eggLightTextureMgr.cpp index 0f77697b..b1aa0cee 100644 --- a/src/egg/gfx/eggLightTextureMgr.cpp +++ b/src/egg/gfx/eggLightTextureMgr.cpp @@ -1,18 +1,26 @@ #include "egg/gfx/eggLightTextureMgr.h" #include "common.h" +#include "egg/gfx/eggDrawGX.h" #include "egg/gfx/eggG3DUtility.h" +#include "egg/gfx/eggLightObject.h" #include "egg/gfx/eggLightTexture.h" #include "egg/gfx/eggStateGX.h" +#include "egg/gfx/eggTextureBuffer.h" #include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/math/math_types.h" +#include "nw4r/ut/ut_Color.h" #include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" +#include "rvl/MTX/mtx44.h" #include namespace EGG { LightTextureManager::LightTextureManager(const LightManager *lightMgr) { - field_0x04 = 0x78; + mFlags = 0x78; mTextureCount = 0; mpTextures = nullptr; mpLightMgr = lightMgr; @@ -25,14 +33,14 @@ LightTextureManager::LightTextureManager(const LightManager *lightMgr) { mpTextures[i] = nullptr; } - mpObjects = new LightObject *[mMaxNumTextures]; + mpObjects = new const LightObject *[mMaxNumTextures]; for (int i = 0; i < mMaxNumTextures; i++) { mpObjects[i] = nullptr; } if ((StateGX::s_flag & 0x40) != 0) { - field_0x04 |= 0x80; - field_0x04 &= ~0x40; + mFlags |= 0x80; + mFlags &= ~0x40; field_0x16 = 3; } } @@ -106,18 +114,37 @@ int LightTextureManager::replaceModelTextures(nw4r::g3d::ResMdl mdl) const { return count; } -int LightTextureManager::replaceModelTexture(u16 tex, nw4r::g3d::ResMdl mdl) const { +int LightTextureManager::replaceModelTexture(int tex, nw4r::g3d::ResMdl mdl) const { if (mpTextures[tex] == nullptr) { return 0; } + + G3DUtility::SetTextureResult buf[256]; GXTexObj obj; mpTextures[tex]->getTexObj(&obj); int count = 0; - for (u32 i = 0; i < mdl.GetResMatNumEntries(); i++) { + for (int i = 0; i < mdl.GetResMatNumEntries(); i++) { nw4r::g3d::ResMat mat = mdl.GetResMat(i); - // TODO - // count += G3DUtility::SetTexture(mat, nullptr, mpLightMgr[tex]->getName(), obj, false, void *param_6, int param_7, int param_8) + + int res = G3DUtility::SetTexture(mat, nullptr, mpTextures[tex]->getName(), &obj, false, buf, 0xFF, 2); + for (int j = 0; j < (u16)res; j++) { + if (buf[j].texCoordId != -1) { + fn_804AE340(mat, static_cast(buf[j].texCoordId)); + } + } + count += res; } + return count; +} + +int LightTextureManager::getTextureIndex(const char *name) const { + for (int i = 0; i < mTextureCount; i++) { + if (!strcmp(name, mpTextures[i]->getName())) { + return i; + } + } + + return -1; } bool LightTextureManager::setBinaryToTexture(const void *data) { @@ -131,6 +158,114 @@ bool LightTextureManager::setBinaryToTexture(const void *data) { return false; } +void LightTextureManager::correctLightObject() { + int j = 0; + for (int i = 0; i < mpLightMgr->GetNumLightData(); i++) { + const LightObject *o = mpLightMgr->GetLightObject(i); + if (o->CheckFlag1() && o->CheckFlag0x20()) { + mpObjects[j] = o; + j++; + if (j >= mMaxNumTextures) { + break; + } + } + } + + for (int i = j; i < mMaxNumTextures; i++) { + mpObjects[i] = nullptr; + } +} + +void LightTextureManager::frameReset() { + correctLightObject(); + field_0x10 = 0; +} + +void LightTextureManager::drawAndCaptureTexture(f32 ox, f32 oy, f32 sx, f32 sy) { + bool b1 = getSomeTfRelatedBool(); + u32 mask1 = 1 << (mpLightMgr->GetField0x1D()); + if ((mFlags & 0x10) == 0 || (field_0x10 & mask1) != 0 || mTextureCount == 0) { + return; + } + + StateGX::resetGXCache(); + if ((mFlags & 0x40) != 0) { + ox = 0.0f; + oy = StateGX::s_heightEfb; + sx = StateGX::s_widthEfb; + sy = 528 - StateGX::s_heightEfb; + } + field_0x10 |= mask1; + + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(false); + + LightTexture::initDrawSetting(ox + ((u16)ox & 1), oy + ((u16)oy & 1), sx, sy); + + u16 x1, y1, x2, y2; + TextureBuffer *buf = nullptr; + LightTexture::getTexDimensions(&x1, &y1, &x2, &y2, mTextureCount); + x2 += x2 & 3; + y2 += y2 & 3; + + if ((mFlags & 0x40) == 0 && (mFlags & 4) != 0) { + buf = TextureBuffer::alloc(x2, y2, GX_TF_RGBA8); + buf->capture(x1, y1, false, -1); + } + + if (b1) { + StateGX::GXSetPixelFmt_(GX_PF_RGB8_Z24, GX_ZC_LINEAR); + } + + nw4r::ut::Color c(StateGX::s_clearEfb); + if (b1 && StateGX::s_pixFormat == GX_PF_RGBA6_Z24) { + // convert GX_PF_RGBA6_Z24 -> GX_PF_RGB8_Z24 + u8 tmp = c.a >> 2; + c = ((c.r >> 2) << 26) | (c.g & 0x3FFC) << 18 | (c.b & 0xFC) << 12 | (tmp & 0x3F) << 8; + } + + bool b2 = b1 && (mFlags & 8) != 0; + for (int i = 0; i < mTextureCount; i++) { + mpTextures[i]->fn_804AC0E0(i, c, b2); + } + + for (int i = 0; i < mTextureCount; i++) { + mpTextures[i]->draw(i); + } + + if (b1) { + StateGX::GXSetPixelFmt_(StateGX::s_pixFormat, StateGX::s_zFmt16); + } + + if ((mFlags & 0x40) == 0 && buf != nullptr) { + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(true); + nw4r::math::MTX44 orthMtx; + C_MTXOrtho(orthMtx, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); + StateGX::GXSetProjection_(orthMtx, GX_ORTHOGRAPHIC); + StateGX::GXSetViewport_(x1, y1, x2, y2, 0.0f, 1.0f); + StateGX::GXSetScissor_(x1, y1, x2, y2); + StateGX::GXSetScissorBoxOffset_(0, 0); + nw4r::math::MTX34 identity; + PSMTXIdentity(identity); + + DrawGX::BeginDrawScreen(1, 1, 0); + DrawGX::SetBlendMode(DrawGX::BLEND_14); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + buf->load(GX_TEXMAP0); + DrawGX::DrawDL(DrawGX::DL_16, identity, DrawGX::WHITE); + buf->free(); + } + + StateGX::invalidateTexAllGX(); + if ((mFlags & 0x80) != 0) { + LightTexture::beginDebugDraw(); + for (int i = 0; i < mTextureCount; i++) { + mpTextures[i]->debugDraw(i); + } + } +} + void LightTextureManager::SetBinaryInner(const Bin &bin) { if (bin.mHeader.mVersion != 0) { return; @@ -172,6 +307,20 @@ const void *LightTextureManager::getLtexFromLmap(const void *lmap, u16 index) { return buf; } +void LightTextureManager::fn_804AE340(nw4r::g3d::ResMat mat, GXTexCoordID id) { + nw4r::g3d::ResTexSrt dat = mat.GetResTexSrt(); + dat.SetMapMode(id, 1, -1, -1); + nw4r::g3d::ResMatTexCoordGen coordGen = mat.GetResMatTexCoordGen(); + + GXTexGenType type; + GXTexGenSrc src; + GXBool normalize; + u32 postMtx; + coordGen.GXGetTexCoordGen2(id, &type, &src, &normalize, &postMtx); + coordGen.GXSetTexCoordGen2(id, GX_TG_MTX3x4, GX_TG_NRM, true, postMtx); + coordGen.DCStore(false); +} + size_t LightTextureManager::GetBinarySize() const { // Contrary to the other dynamically-sized Bins, this only // returns the fixed size. GetBinaryInner will add the dynamic From 8c4f34add715b30b67829cbe378ec04557dea566 Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 27 Mar 2025 20:59:42 +0100 Subject: [PATCH 47/62] ModelEx OK --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 16 ++--- configure.py | 2 +- include/egg/gfx/eggAnalizeDL.h | 36 ++++++++++ include/egg/gfx/eggG3DUtility.h | 13 +++- include/egg/gfx/eggIScnProcModel.h | 24 +++++++ include/egg/gfx/eggModelEx.h | 2 +- src/egg/gfx/eggModelEx.cpp | 101 ++++++++++++++++++++++++++++- 8 files changed, 181 insertions(+), 14 deletions(-) create mode 100644 include/egg/gfx/eggAnalizeDL.h create mode 100644 include/egg/gfx/eggIScnProcModel.h diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index a23f47c7..1c73867d 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2284,6 +2284,7 @@ egg/gfx/eggLightTextureMgr.cpp: egg/gfx/eggModelEx.cpp: .text start:0x804AE650 end:0x804AEC20 + .rodata start:0x804FBD08 end:0x804FBD50 .data start:0x8056F110 end:0x8056F120 .sdata start:0x80574F48 end:0x80574F60 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 3cb741c6..ae89f5f3 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26423,10 +26423,10 @@ attachPalette__Q23EGG7TextureFPQ23EGG7Palette = .text:0x8049CD60; // type:functi initTexObj__Q23EGG7TextureFv = .text:0x8049CDA0; // type:function size:0xF0 initTexObj__Q23EGG7TextureF7_GXTlut = .text:0x8049CE90; // type:function size:0xF8 load__Q23EGG7TextureF11_GXTexMapID = .text:0x8049CF90; // type:function size:0x54 -FUN_8049cff0 = .text:0x8049CFF0; // type:function size:0x12C -FUN_8049d120 = .text:0x8049D120; // type:function size:0x590 +__ct__Q23EGG9AnalizeDLFQ34nw4r3g3d6ResShp = .text:0x8049CFF0; // type:function size:0x12C +step__Q23EGG9AnalizeDLFv = .text:0x8049D120; // type:function size:0x590 FUN_8049d6b0 = .text:0x8049D6B0; // type:function size:0xB8 -FUN_8049d770 = .text:0x8049D770; // type:function size:0x8 +getVtxResult__Q23EGG9AnalizeDLCFv = .text:0x8049D770; // type:function size:0x8 FUN_8049d780 = .text:0x8049D780; // type:function size:0x40 configure__Q23EGG10CapTextureFv = .text:0x8049D7C0; // type:function size:0x7C capture__Q23EGG10CapTextureFUsUsbi = .text:0x8049D840; // type:function size:0x184 @@ -26564,12 +26564,12 @@ __sinit_\eggFrustum_cpp = .text:0x804A6830; // type:function size:0x24 scope:loc FUN_804a6860 = .text:0x804A6860; // type:function size:0x104 FUN_804a6970 = .text:0x804A6970; // type:function size:0x34 setUpLightSet__Q23EGG10G3DUtilityFRQ34nw4r3g3d12LightSettingQ34nw4r3g3d9ResAnmScni = .text:0x804A69B0; // type:function size:0x1E8 -FUN_804a6ba0 = .text:0x804A6BA0; // type:function size:0x104 -FUN_804a6cb0 = .text:0x804A6CB0; // type:function size:0x104 -FUN_804a6dc0 = .text:0x804A6DC0; // type:function size:0x144 +searchStringResNode__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcPUsUl = .text:0x804A6BA0; // type:function size:0x104 +searchStringResMat__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcPUsUl = .text:0x804A6CB0; // type:function size:0x104 +searchStringResTexPlttInfo__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcPUsUl = .text:0x804A6DC0; // type:function size:0x144 SetTexture__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMatPQ44nw4r3g3d6ScnMdl15CopiedMatAccessPCcP9_GXTexObjbPQ33EGG10G3DUtility16SetTextureResultii = .text:0x804A6F10; // type:function size:0x350 FUN_804a7260 = .text:0x804A7260; // type:function size:0x31C -FUN_804a7580 = .text:0x804A7580; // type:function size:0x30 +GetWorldMtxArray__Q23EGG10G3DUtilityFii = .text:0x804A7580; // type:function size:0x30 __dt__Q33EGG9GfxEngine13ConfigurationFv = .text:0x804A75B0; // type:function size:0x40 __ct__Q33EGG9GfxEngine13ConfigurationFv = .text:0x804A75F0; // type:function size:0x154 beginDrawView__Q23EGG15GlobalDrawStateFUsRCQ34nw4r4math5MTX34RCQ23EGG6Screen = .text:0x804A7750; // type:function size:0x3C @@ -26686,7 +26686,7 @@ GetBinary__Q23EGG29IBinaryCFPv = .text:0x804AE430; // type __ct__Q23EGG7ModelExFPQ34nw4r3g3d6ScnObj = .text:0x804AE650; // type:function size:0x1C8 getShapeMinMax__Q23EGG7ModelExFUsPQ34nw4r4math4VEC3PQ34nw4r4math4VEC3b = .text:0x804AE820; // type:function size:0x228 calcWorld__Q23EGG7ModelExCFPQ34nw4r4math5MTX34PCQ34nw4r4math5MTX34 = .text:0x804AEA50; // type:function size:0xF0 -getResMdl__Q23EGG7ModelExCFUs = .text:0x804AEB40; // type:function size:0x48 +getResMdl__Q23EGG7ModelExCFv = .text:0x804AEB40; // type:function size:0x48 getResShp__Q23EGG7ModelExCFUs = .text:0x804AEB90; // type:function size:0x90 __ct__Q23EGG14PostEffectBaseFv = .text:0x804AEC20; // type:function size:0x5C draw__Q23EGG14PostEffectBaseFff = .text:0x804AEC80; // type:function size:0x94 diff --git a/configure.py b/configure.py index cb7cacf2..55351e1e 100644 --- a/configure.py +++ b/configure.py @@ -888,7 +888,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggLightObject.cpp"), Object(NonMatching, "egg/gfx/eggLightTexture.cpp"), Object(Matching, "egg/gfx/eggLightTextureMgr.cpp"), - Object(NonMatching, "egg/gfx/eggModelEx.cpp"), + Object(Matching, "egg/gfx/eggModelEx.cpp"), Object(Matching, "egg/gfx/eggPostEffectBase.cpp"), Object(Matching, "egg/gfx/eggPostEffectBlur.cpp"), Object(Matching, "egg/gfx/eggPostEffectBlurGather.cpp"), diff --git a/include/egg/gfx/eggAnalizeDL.h b/include/egg/gfx/eggAnalizeDL.h new file mode 100644 index 00000000..cb7d2c14 --- /dev/null +++ b/include/egg/gfx/eggAnalizeDL.h @@ -0,0 +1,36 @@ +#ifndef EGG_ANALIZE_DL_H +#define EGG_ANALIZE_DL_H + +#include "nw4r/g3d/res/g3d_resshp.h" + +namespace EGG { + +class AnalizeDL { +public: + enum Status { + STATUS_NONE, + + STATUS_VTX = 4, + STATUS_ERROR = 6, + }; + + struct VtxResult { + /* 0x00 */ s32 mMtxIdx; + /* 0x04 */ u8 _0x04[4]; + /* 0x08 */ Vec field_0x08; + }; + +private: + u8 _0x000[0x1E4 - 0x000]; + +public: + AnalizeDL(nw4r::g3d::ResShp shp); + virtual ~AnalizeDL() {} + + Status step(); + const VtxResult &getVtxResult() const; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggG3DUtility.h b/include/egg/gfx/eggG3DUtility.h index 15250313..7ad5a736 100644 --- a/include/egg/gfx/eggG3DUtility.h +++ b/include/egg/gfx/eggG3DUtility.h @@ -3,6 +3,7 @@ #include "nw4r/g3d/g3d_scnmdl.h" #include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/math/math_types.h" #include "rvl/MEM/mem_allocator.h" namespace EGG { @@ -20,12 +21,20 @@ public: }; static u32 SetTexture( - nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *param_2, const char *name, GXTexObj *texObj, bool copy, - SetTextureResult *pResult, int param_7, int param_8 + nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *param_2, const char *name, GXTexObj *texObj, + bool copy, SetTextureResult *pResult, int param_7, int param_8 ); static void setUpLightSet(nw4r::g3d::LightSetting &, nw4r::g3d::ResAnmScn, int); + static nw4r::math::MTX34 *GetWorldMtxArray(int, int); + + static int searchStringResNode(nw4r::g3d::ResMdl, const char *, u16 *, u32); + static int searchStringResMat(nw4r::g3d::ResMdl, const char *, u16 *, u32); + static int searchStringResTexPlttInfo(nw4r::g3d::ResMdl, const char *, u16 *, u32); + + typedef int (*MdlSearch)(nw4r::g3d::ResMdl, const char *, u16 *, u32); + private: static MEMAllocator *sAllocator; }; diff --git a/include/egg/gfx/eggIScnProcModel.h b/include/egg/gfx/eggIScnProcModel.h new file mode 100644 index 00000000..254d4832 --- /dev/null +++ b/include/egg/gfx/eggIScnProcModel.h @@ -0,0 +1,24 @@ +#ifndef EGG_I_SCN_PROC_MODEL_H +#define EGG_I_SCN_PROC_MODEL_H + +#include "common.h" +#include "nw4r/math/math_types.h" + +namespace EGG { + +class IScnProcModel { +private: + /* 0x00 */ u8 _0x00[0x08]; + +public: + IScnProcModel() {} + virtual ~IScnProcModel() {} // at 0x8 + virtual void draw(bool, u32) = 0; // at 0xC + virtual UNKTYPE VF_0x10(UNKTYPE) = 0; // at 0x10 + virtual UNKTYPE VF_0x14(UNKTYPE) = 0; // at 0x14 + virtual void getMinMaxScnProcModel(nw4r::math::VEC3 *, nw4r::math::VEC3 *) const = 0; // at 0x18 +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggModelEx.h b/include/egg/gfx/eggModelEx.h index 5ef3fdb3..9e8aa23f 100644 --- a/include/egg/gfx/eggModelEx.h +++ b/include/egg/gfx/eggModelEx.h @@ -40,7 +40,7 @@ public: ModelEx(nw4r::g3d::ScnObj *); void getShapeMinMax(u16, nw4r::math::VEC3 *, nw4r::math::VEC3 *, bool); void calcWorld(nw4r::math::MTX34 *, const nw4r::math::MTX34 *worldMtx) const; - nw4r::g3d::ResMdl getResMdl(u16) const; + nw4r::g3d::ResMdl getResMdl() const; nw4r::g3d::ResShp getResShp(u16) const; nw4r::g3d::ScnMdl *getScnMdl() const { diff --git a/src/egg/gfx/eggModelEx.cpp b/src/egg/gfx/eggModelEx.cpp index cd28528f..6a6e4cd2 100644 --- a/src/egg/gfx/eggModelEx.cpp +++ b/src/egg/gfx/eggModelEx.cpp @@ -1,11 +1,19 @@ #include "egg/gfx/eggModelEx.h" #include "common.h" +#include "egg/gfx/eggAnalizeDL.h" +#include "egg/gfx/eggG3DUtility.h" +#include "egg/gfx/eggIScnProcModel.h" #include "nw4r/g3d/g3d_calcworld.h" #include "nw4r/g3d/g3d_scnmdl.h" #include "nw4r/g3d/g3d_scnmdl1mat1shp.h" #include "nw4r/g3d/g3d_scnmdlsmpl.h" +#include "nw4r/g3d/g3d_scnproc.h" #include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resshp.h" +#include "nw4r/math/math_types.h" +#include "rvl/MTX/mtx.h" +#include "rvl/MTX/mtxvec.h" namespace EGG { @@ -25,7 +33,96 @@ ModelEx::ModelEx(g3d::ScnObj *obj) } } -void ModelEx::getShapeMinMax(u16 shapeIndex, math::VEC3 *pMin, math::VEC3 *pMax, bool doCalcWorld) {} +static const f32 sFaceMin[] = {-22.61115f, -55.770135f, -45.93067f}; +static const f32 sFaceMax[] = {81.17467f, 49.677597f, 45.93065f}; + +static const f32 sNoneMin[] = {0.0f, 0.0f, 0.0f}; +static const f32 sNoneMax[] = {0.0f, 0.0f, 0.0f}; + +// Not sure what this was for but it didn't get stripped due to data pooling +static const G3DUtility::MdlSearch sMdlSearch[6] = { + G3DUtility::searchStringResNode, G3DUtility::searchStringResMat, G3DUtility::searchStringResTexPlttInfo, + G3DUtility::searchStringResNode, G3DUtility::searchStringResMat, G3DUtility::searchStringResTexPlttInfo, +}; + +void thisProbablyGotDeadStripped() { + sMdlSearch[0](g3d::ResMdl(nullptr), "", nullptr, 0); +} + +extern "C" s32 lbl_8057682C; + +void ModelEx::getShapeMinMax(u16 shapeIndex, math::VEC3 *pMin, math::VEC3 *pMax, bool doCalcWorld) { + switch (mType) { + case cType_ScnMdlSimple: + case cType_ScnMdl: + case cType_ScnMdl1Mat1Shp: { + g3d::ResShp shp = getResShp(shapeIndex); + lbl_8057682C = 0; + g3d::ResMdl mdl = getResMdl(); + math::MTX34 tmpMtx; + g3d::ResMdlInfo info = mdl.GetResMdlInfo(); + math::MTX34 *pMtxArr = G3DUtility::GetWorldMtxArray(info.GetNumPosNrmMtx() * sizeof(math::MTX34), 1); + if (doCalcWorld) { + PSMTXIdentity(tmpMtx); + calcWorld(pMtxArr, &tmpMtx); + } + + s32 defaultMatrixIdx = shp.ref().curMtxIdx; + AnalizeDL analyze(shp); + + bool firstIteration = true; + AnalizeDL::Status status; + while ((status = analyze.step()) != AnalizeDL::STATUS_ERROR) { + if (status != AnalizeDL::STATUS_VTX) { + continue; + } + + const AnalizeDL::VtxResult &result = analyze.getVtxResult(); + s32 mtxIdx = result.mMtxIdx; + if (mtxIdx == -1) { + mtxIdx = defaultMatrixIdx; + } + nw4r::math::VEC3 tmpVec; + PSMTXMultVec(pMtxArr[mtxIdx], &analyze.getVtxResult().field_0x08, tmpVec); + if (firstIteration) { + firstIteration = false; + *pMin = *pMax = tmpVec; + } else { + math::VEC3Minimize(pMin, pMin, &tmpVec); + math::VEC3Maximize(pMax, pMax, &tmpVec); + } + } + lbl_8057682C = 0; + break; + } + case cType_ScnProcModel: + static_cast(static_cast(mScnObj)->GetUserData()) + ->getMinMaxScnProcModel(pMin, pMax); + break; + case cType_ScnRfl: { + const f32 *min = sFaceMin; + const f32 *max = sFaceMax; + pMin->x = min[0]; + pMin->y = min[1]; + pMin->z = min[2]; + pMax->x = max[0]; + pMax->y = max[1]; + pMax->z = max[2]; + break; + } + + case cType_None: + const f32 *min = sNoneMin; + const f32 *max = sNoneMax; + pMin->x = min[0]; + pMin->y = min[1]; + pMin->z = min[2]; + pMax->x = max[0]; + pMax->y = max[1]; + pMax->z = max[2]; + break; + } +} void ModelEx::calcWorld(math::MTX34 *pWorldMtxArray, const math::MTX34 *worldMtx) const { switch (mType) { @@ -53,7 +150,7 @@ void ModelEx::calcWorld(math::MTX34 *pWorldMtxArray, const math::MTX34 *worldMtx } } -g3d::ResMdl ModelEx::getResMdl(u16) const { +g3d::ResMdl ModelEx::getResMdl() const { g3d::ScnMdlSimple *mdl = getScnMdlSimple(); if (mdl != nullptr) { return mdl->GetResMdl(); From 87ab862b9129c9e25457f1c87a102c92fa266f0b Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 27 Mar 2025 23:02:44 +0100 Subject: [PATCH 48/62] AnalizeDL mostly OK --- config/SOUE01/splits.txt | 2 + config/SOUE01/symbols.txt | 6 +- configure.py | 2 +- include/egg/gfx/eggAnalizeDL.h | 32 +++++- src/egg/gfx/eggAnalizeDL.cpp | 185 +++++++++++++++++++++++++++++++++ src/egg/gfx/eggModelEx.cpp | 2 +- 6 files changed, 220 insertions(+), 9 deletions(-) create mode 100644 src/egg/gfx/eggAnalizeDL.cpp diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 1c73867d..edcd20d2 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2179,6 +2179,8 @@ egg/gfx/eggTexture.cpp: egg/gfx/eggAnalizeDL.cpp: .text start:0x8049CFF0 end:0x8049D7C0 + .data start:0x8056ED60 end:0x8056ED70 + .sdata2 start:0x8057F3E0 end:0x8057F408 egg/gfx/eggCapTexture.cpp: .text start:0x8049D7C0 end:0x8049D9C4 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index ae89f5f3..cd7a3b3f 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26425,9 +26425,9 @@ initTexObj__Q23EGG7TextureF7_GXTlut = .text:0x8049CE90; // type:function size:0x load__Q23EGG7TextureF11_GXTexMapID = .text:0x8049CF90; // type:function size:0x54 __ct__Q23EGG9AnalizeDLFQ34nw4r3g3d6ResShp = .text:0x8049CFF0; // type:function size:0x12C step__Q23EGG9AnalizeDLFv = .text:0x8049D120; // type:function size:0x590 -FUN_8049d6b0 = .text:0x8049D6B0; // type:function size:0xB8 +init__Q23EGG9AnalizeDLFv = .text:0x8049D6B0; // type:function size:0xB8 getVtxResult__Q23EGG9AnalizeDLCFv = .text:0x8049D770; // type:function size:0x8 -FUN_8049d780 = .text:0x8049D780; // type:function size:0x40 +__dt__Q23EGG9AnalizeDLFv = .text:0x8049D780; // type:function size:0x40 configure__Q23EGG10CapTextureFv = .text:0x8049D7C0; // type:function size:0x7C capture__Q23EGG10CapTextureFUsUsbi = .text:0x8049D840; // type:function size:0x184 FUN_8049d9d0 = .text:0x8049D9D0; // type:function size:0x58 @@ -37354,7 +37354,7 @@ __vt__Q23EGG14CoreController = .data:0x8056EC50; // type:object size:0x38 @3881 = .data:0x8056ECF0; // type:object size:0x10 scope:local data:string __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__Q23EGG9AnalizeDL = .data:0x8056ED60; // type:object size:0xC __vt__Q23EGG10CapTexture = .data:0x8056ED70; // type:object size:0x10 __vt__Q23EGG10CpuTexture = .data:0x8056ED80; // type:object size:0x10 DummyTexureData = .data:0x8056EDA0; // type:object size:0x40 diff --git a/configure.py b/configure.py index 55351e1e..2f70eac1 100644 --- a/configure.py +++ b/configure.py @@ -868,7 +868,7 @@ config.libs = [ Object(Matching, "egg/gfx/eggCamera.cpp"), Object(Matching, "egg/gfx/eggPalette.cpp"), Object(Matching, "egg/gfx/eggTexture.cpp"), - Object(NonMatching, "egg/gfx/eggUnk1.cpp"), # Unknown + Object(NonMatching, "egg/gfx/eggAnalizeDL.cpp"), Object(Matching, "egg/gfx/eggCapTexture.cpp"), Object(NonMatching, "egg/gfx/eggCpuTexture.cpp"), Object(NonMatching, "egg/gfx/eggDrawGX.cpp"), diff --git a/include/egg/gfx/eggAnalizeDL.h b/include/egg/gfx/eggAnalizeDL.h index cb7d2c14..f89cfa7b 100644 --- a/include/egg/gfx/eggAnalizeDL.h +++ b/include/egg/gfx/eggAnalizeDL.h @@ -2,6 +2,7 @@ #define EGG_ANALIZE_DL_H #include "nw4r/g3d/res/g3d_resshp.h" +#include "rvl/GX/GXAttr.h" namespace EGG { @@ -9,19 +10,42 @@ class AnalizeDL { public: enum Status { STATUS_NONE, - + STATUS_1, + STATUS_2, + STATUS_3, STATUS_VTX = 4, - STATUS_ERROR = 6, + STATUS_5, + STATUS_END = 6, }; struct VtxResult { /* 0x00 */ s32 mMtxIdx; - /* 0x04 */ u8 _0x04[4]; + /* 0x04 */ s32 field_0x04; /* 0x08 */ Vec field_0x08; }; private: - u8 _0x000[0x1E4 - 0x000]; + /* 0x000 */ u8 *mpData; + /* 0x004 */ u32 mBufSize; + /* 0x008 */ u32 mCursor; + /* 0x00C */ u8 field_0x00C; + /* 0x00D */ u8 field_0x00D; + /* 0x00E */ u8 field_0x00E; + /* 0x00F */ u8 field_0x00F; + /* 0x010 */ u16 field_0x010; + /* 0x014 */ GXVtxDescList mVtxDescList[22]; + /* 0x0C4 */ GXVtxAttrFmtList mAttrFmtList[13]; + /* 0x194 */ u8 mArrStride; + /* 0x198 */ const void *mpArr; + /* 0x19C */ Status mStatus; + /* 0x1A0 */ s16 field_0x1A0[10]; + /* 0x1B4 */ s16 field_0x1B4[10]; + /* 0x1C8 */ u8 field_0x1C8; + /* 0x1CA */ u16 field_0x1CA; + /* 0x1CC */ u16 field_0x1CC; + /* 0x1D0 */ VtxResult mVtxResult; + + void init(); public: AnalizeDL(nw4r::g3d::ResShp shp); diff --git a/src/egg/gfx/eggAnalizeDL.cpp b/src/egg/gfx/eggAnalizeDL.cpp new file mode 100644 index 00000000..5389a17c --- /dev/null +++ b/src/egg/gfx/eggAnalizeDL.cpp @@ -0,0 +1,185 @@ +#include "egg/gfx/eggAnalizeDL.h" + +#include "nw4r/g3d/res/g3d_resshp.h" +#include "nw4r/g3d/res/g3d_resvtx.h" + +namespace EGG { + +AnalizeDL::AnalizeDL(nw4r::g3d::ResShp shp) { + mpData = shp.GetPrimDLTag().GetDL(); + mBufSize = shp.GetPrimDLTag().GetBufSize(); + mCursor = 0; + field_0x00C = 0; + shp.GXGetVtxDescv(mVtxDescList); + shp.GXGetVtxAttrFmtv(mAttrFmtList); + field_0x00E = 0; + field_0x00F = 0; + field_0x010 = 0; + + init(); + nw4r::g3d::ResVtxPos pos = shp.GetResVtxPos(); + pos.GetArray(&mpArr, &mArrStride); + mStatus = STATUS_NONE; + field_0x1CC = 0; + + for (int i = 0; i < 10; i++) { + field_0x1A0[i] = -1; + field_0x1B4[i] = -1; + } +} + +AnalizeDL::Status AnalizeDL::step() { + if (mBufSize <= mCursor) { + mStatus = STATUS_END; + } else if (field_0x1CC == 0) { + u8 *pCommand = &mpData[mCursor]; + u8 command = pCommand[0]; + switch (command) { + case 0x20: + field_0x1A0[pCommand[4] / 12] = pCommand[2]; + mStatus = STATUS_1; + mCursor += 5; + break; + case 0x28: + field_0x1B4[pCommand[4] / 9] = pCommand[2]; + mStatus = STATUS_2; + mCursor += 5; + break; + case 0x30: mCursor += 5; break; + case 0x90: + case 0xA8: + case 0xB8: + case 0xB0: + case 0xA0: + case 0x98: + case 0x80: + field_0x1C8 = command; + field_0x1CA = *reinterpret_cast(pCommand + 1); + field_0x1CC = field_0x1CA; + mStatus = STATUS_3; + mCursor += 3; + break; + case 0x0: mCursor += 1; break; + default: mCursor += 1; break; + } + } else { + u8 *pCommand = &mpData[mCursor]; + if ((field_0x010 & 1) != 0) { + mVtxResult.mMtxIdx = field_0x1A0[*(pCommand++) / 3]; + } else { + mVtxResult.mMtxIdx = -1; + } + + for (int i = 0; i < 8; i++) { + if ((field_0x010 & (1 << (i + 1))) != 0) { + pCommand++; + } + } + + if ((field_0x010 & 0x200) != 0) { + if (field_0x00F == 1) { + mVtxResult.field_0x04 = *pCommand; + } else { + mVtxResult.field_0x04 = *reinterpret_cast(pCommand); + } + + GXCompType compType = mAttrFmtList[0].compType; + u8 shift = mAttrFmtList[0].shift; + // REGSWAP + const void *pData = reinterpret_cast(mpArr) + (mArrStride * mVtxResult.field_0x04); + switch (compType) { + case GX_U8: { + int val = 1 << shift; + const u8 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0] / (f32)val; + mVtxResult.field_0x08.y = dat[1] / (f32)val; + mVtxResult.field_0x08.z = dat[2] / (f32)val; + break; + } + case GX_S8: { + int val = 1 << shift; + const s8 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0] / (f32)val; + mVtxResult.field_0x08.y = dat[1] / (f32)val; + mVtxResult.field_0x08.z = dat[2] / (f32)val; + break; + } + case GX_U16: { + int val = 1 << shift; + const u16 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0] / (f32)val; + mVtxResult.field_0x08.y = dat[1] / (f32)val; + mVtxResult.field_0x08.z = dat[2] / (f32)val; + break; + } + case GX_S16: { + int val = 1 << shift; + const s16 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0] / (f32)val; + mVtxResult.field_0x08.y = dat[1] / (f32)val; + mVtxResult.field_0x08.z = dat[2] / (f32)val; + break; + } + case GX_F32: { + const f32 *dat = reinterpret_cast(pData); + mVtxResult.field_0x08.x = dat[0]; + mVtxResult.field_0x08.y = dat[1]; + mVtxResult.field_0x08.z = dat[2]; + break; + } + default: break; + } + } else { + mVtxResult.field_0x04 = -1; + mVtxResult.field_0x08.z = 0.0f; + mVtxResult.field_0x08.y = 0.0f; + mVtxResult.field_0x08.x = 0.0f; + } + field_0x1CC -= 1; + mStatus = STATUS_VTX; + mCursor += field_0x00E; + } + + return mStatus; +} + +static const s8 sArr1[] = {0, -1, 1, 2}; +static const u8 sArr2[] = {1, 1, 2, 2, 4, 0}; + +void AnalizeDL::init() { + // TODO + int k = 0; + const u8 *pArr2 = sArr2; + const s8 *pArr1 = sArr1; + + for (int i = 0; mVtxDescList[i].attr != GX_VA_NULL; i++) { + int x = pArr1[mVtxDescList[i].type]; + pArr1++; + if (x == -1) { + if (k >= 0 && k <= 8) { + x = 1; + } + } else { + int j = 1; + for (; k != mAttrFmtList[j].attr; j++) {} + x = pArr2[mAttrFmtList[j - 1].compType]; + } + + if (k == 9) { + field_0x00F = x; + } + + field_0x00E += x; + if (x != 0) { + field_0x010 |= (1 << k); + } + + k++; + } +} + +const AnalizeDL::VtxResult &AnalizeDL::getVtxResult() const { + return mVtxResult; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggModelEx.cpp b/src/egg/gfx/eggModelEx.cpp index 6a6e4cd2..daa9d196 100644 --- a/src/egg/gfx/eggModelEx.cpp +++ b/src/egg/gfx/eggModelEx.cpp @@ -72,7 +72,7 @@ void ModelEx::getShapeMinMax(u16 shapeIndex, math::VEC3 *pMin, math::VEC3 *pMax, bool firstIteration = true; AnalizeDL::Status status; - while ((status = analyze.step()) != AnalizeDL::STATUS_ERROR) { + while ((status = analyze.step()) != AnalizeDL::STATUS_END) { if (status != AnalizeDL::STATUS_VTX) { continue; } From 5477b7b547b02dbc83541a2177709dbc75288d0e Mon Sep 17 00:00:00 2001 From: robojumper Date: Thu, 27 Mar 2025 23:54:20 +0100 Subject: [PATCH 49/62] Fix Regswap --- src/egg/gfx/eggAnalizeDL.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/egg/gfx/eggAnalizeDL.cpp b/src/egg/gfx/eggAnalizeDL.cpp index 5389a17c..018897fe 100644 --- a/src/egg/gfx/eggAnalizeDL.cpp +++ b/src/egg/gfx/eggAnalizeDL.cpp @@ -54,7 +54,7 @@ AnalizeDL::Status AnalizeDL::step() { case 0x98: case 0x80: field_0x1C8 = command; - field_0x1CA = *reinterpret_cast(pCommand + 1); + field_0x1CA = *reinterpret_cast(pCommand + 1); field_0x1CC = field_0x1CA; mStatus = STATUS_3; mCursor += 3; @@ -83,13 +83,15 @@ AnalizeDL::Status AnalizeDL::step() { mVtxResult.field_0x04 = *reinterpret_cast(pCommand); } - GXCompType compType = mAttrFmtList[0].compType; + int val; u8 shift = mAttrFmtList[0].shift; - // REGSWAP - const void *pData = reinterpret_cast(mpArr) + (mArrStride * mVtxResult.field_0x04); - switch (compType) { + + const u8 *pData = static_cast(mpArr); + pData += mArrStride * mVtxResult.field_0x04; + + switch (mAttrFmtList[0].compType) { case GX_U8: { - int val = 1 << shift; + val = 1 << shift; const u8 *dat = reinterpret_cast(pData); mVtxResult.field_0x08.x = dat[0] / (f32)val; mVtxResult.field_0x08.y = dat[1] / (f32)val; @@ -97,7 +99,7 @@ AnalizeDL::Status AnalizeDL::step() { break; } case GX_S8: { - int val = 1 << shift; + val = 1 << shift; const s8 *dat = reinterpret_cast(pData); mVtxResult.field_0x08.x = dat[0] / (f32)val; mVtxResult.field_0x08.y = dat[1] / (f32)val; @@ -105,7 +107,7 @@ AnalizeDL::Status AnalizeDL::step() { break; } case GX_U16: { - int val = 1 << shift; + val = 1 << shift; const u16 *dat = reinterpret_cast(pData); mVtxResult.field_0x08.x = dat[0] / (f32)val; mVtxResult.field_0x08.y = dat[1] / (f32)val; @@ -113,7 +115,7 @@ AnalizeDL::Status AnalizeDL::step() { break; } case GX_S16: { - int val = 1 << shift; + val = 1 << shift; const s16 *dat = reinterpret_cast(pData); mVtxResult.field_0x08.x = dat[0] / (f32)val; mVtxResult.field_0x08.y = dat[1] / (f32)val; From 0766801142a25efcad59e98b77bca43b1c02bae0 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 28 Mar 2025 10:23:57 +0100 Subject: [PATCH 50/62] Link AnalizeDL with a fakematch (?) --- configure.py | 2 +- src/egg/gfx/eggAnalizeDL.cpp | 22 ++++++++-------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/configure.py b/configure.py index 2f70eac1..c8b73a79 100644 --- a/configure.py +++ b/configure.py @@ -868,7 +868,7 @@ config.libs = [ Object(Matching, "egg/gfx/eggCamera.cpp"), Object(Matching, "egg/gfx/eggPalette.cpp"), Object(Matching, "egg/gfx/eggTexture.cpp"), - Object(NonMatching, "egg/gfx/eggAnalizeDL.cpp"), + Object(Matching, "egg/gfx/eggAnalizeDL.cpp"), Object(Matching, "egg/gfx/eggCapTexture.cpp"), Object(NonMatching, "egg/gfx/eggCpuTexture.cpp"), Object(NonMatching, "egg/gfx/eggDrawGX.cpp"), diff --git a/src/egg/gfx/eggAnalizeDL.cpp b/src/egg/gfx/eggAnalizeDL.cpp index 018897fe..e8febe68 100644 --- a/src/egg/gfx/eggAnalizeDL.cpp +++ b/src/egg/gfx/eggAnalizeDL.cpp @@ -149,22 +149,18 @@ static const s8 sArr1[] = {0, -1, 1, 2}; static const u8 sArr2[] = {1, 1, 2, 2, 4, 0}; void AnalizeDL::init() { - // TODO - int k = 0; - const u8 *pArr2 = sArr2; - const s8 *pArr1 = sArr1; - - for (int i = 0; mVtxDescList[i].attr != GX_VA_NULL; i++) { - int x = pArr1[mVtxDescList[i].type]; - pArr1++; + for (int k = 0, i = 0; mVtxDescList[i].attr != GX_VA_NULL; k++, i++) { + // Likely a fakematch + int x = sArr1[mVtxDescList[i++, --i].type]; if (x == -1) { if (k >= 0 && k <= 8) { x = 1; + } else { + int j = -1; + while (k != mAttrFmtList[++j].attr) {} + + x = sArr2[mAttrFmtList[j].compType]; } - } else { - int j = 1; - for (; k != mAttrFmtList[j].attr; j++) {} - x = pArr2[mAttrFmtList[j - 1].compType]; } if (k == 9) { @@ -175,8 +171,6 @@ void AnalizeDL::init() { if (x != 0) { field_0x010 |= (1 << k); } - - k++; } } From d35c4adeeffc0629f705518aedd9e8d4b4570364 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 28 Mar 2025 18:42:09 +0100 Subject: [PATCH 51/62] Running out of ideas for G3DUtility --- config/SOUE01/symbols.txt | 24 +- include/egg/gfx/eggG3DUtility.h | 37 +- include/egg/gfx/eggLightTextureMgr.h | 4 +- include/nw4r/g3d/res/g3d_resmat.h | 36 ++ include/nw4r/g3d/res/g3d_resmdl.h | 2 +- include/nw4r/g3d/res/g3d_resnode.h | 13 +- include/rvl/GX/GXTexture.h | 3 + .../MSL/MSL_C/MSL_Common/Include/cstring | 2 +- .../MSL/MSL_C/MSL_Common/Include/string.h | 1 + src/egg/gfx/eggG3DUtility.cpp | 378 +++++++++++++++++- src/egg/gfx/eggLightTextureMgr.cpp | 12 +- src/egg/gfx/eggModelEx.cpp | 11 +- src/nw4r/g3d/res/g3d_resmdl.cpp | 5 +- src/toBeSorted/arc_callback_handler.cpp | 5 +- 14 files changed, 488 insertions(+), 45 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index cd7a3b3f..560bd020 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26561,15 +26561,15 @@ GetPerspectiveParam___Q23EGG7FrustumCFPf = .text:0x804A6520; // type:function si GetOrthographicParam___Q23EGG7FrustumCFPf = .text:0x804A65E0; // type:function size:0xE0 GetOrthographicParam___Q23EGG7FrustumCFPfPfPfPf = .text:0x804A66C0; // type:function size:0x164 __sinit_\eggFrustum_cpp = .text:0x804A6830; // type:function size:0x24 scope:local -FUN_804a6860 = .text:0x804A6860; // type:function size:0x104 -FUN_804a6970 = .text:0x804A6970; // type:function size:0x34 +create__Q23EGG10G3DUtilityFUlPQ23EGG4Heap = .text:0x804A6860; // type:function size:0x104 +defaultTexMtxFunc__Q23EGG10G3DUtilityFPQ34nw4r4math5MTX34ScSc = .text:0x804A6970; // type:function size:0x34 setUpLightSet__Q23EGG10G3DUtilityFRQ34nw4r3g3d12LightSettingQ34nw4r3g3d9ResAnmScni = .text:0x804A69B0; // type:function size:0x1E8 -searchStringResNode__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcPUsUl = .text:0x804A6BA0; // type:function size:0x104 -searchStringResMat__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcPUsUl = .text:0x804A6CB0; // type:function size:0x104 -searchStringResTexPlttInfo__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcPUsUl = .text:0x804A6DC0; // type:function size:0x144 -SetTexture__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMatPQ44nw4r3g3d6ScnMdl15CopiedMatAccessPCcP9_GXTexObjbPQ33EGG10G3DUtility16SetTextureResultii = .text:0x804A6F10; // type:function size:0x350 -FUN_804a7260 = .text:0x804A7260; // type:function size:0x31C -GetWorldMtxArray__Q23EGG10G3DUtilityFii = .text:0x804A7580; // type:function size:0x30 +searchStringResNode__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcbPQ33EGG10G3DUtility12SearchResulti = .text:0x804A6BA0; // type:function size:0x104 +searchStringResMat__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcbPQ33EGG10G3DUtility12SearchResulti = .text:0x804A6CB0; // type:function size:0x104 +searchStringResTexPlttInfo__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcbPQ33EGG10G3DUtility12SearchResulti = .text:0x804A6DC0; // type:function size:0x144 +SetTexture__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMatPQ44nw4r3g3d6ScnMdl15CopiedMatAccessPCcPC9_GXTexObjbPQ33EGG10G3DUtility16SetTextureResultii = .text:0x804A6F10; // type:function size:0x350 +ApplyLightMat__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCc = .text:0x804A7260; // type:function size:0x31C +BumpAlloc__Q23EGG10G3DUtilityFUlUl = .text:0x804A7580; // type:function size:0x30 __dt__Q33EGG9GfxEngine13ConfigurationFv = .text:0x804A75B0; // type:function size:0x40 __ct__Q33EGG9GfxEngine13ConfigurationFv = .text:0x804A75F0; // type:function size:0x154 beginDrawView__Q23EGG15GlobalDrawStateFUsRCQ34nw4r4math5MTX34RCQ23EGG6Screen = .text:0x804A7750; // type:function size:0x3C @@ -41151,11 +41151,11 @@ s_flag__Q23EGG6DrawGX = .sbss:0x80576808; // type:object size:0x4 data:4byte sTexMapDefault__Q23EGG6DrawGX = .sbss:0x8057680C; // type:object size:0x4 data:4byte sGlobalScale__Q23EGG7Frustum = .sbss:0x80576810; // type:object size:0x8 data:float sGlobalOffset__Q23EGG7Frustum = .sbss:0x80576818; // type:object size:0x8 data:float -lbl_80576820 = .sbss:0x80576820; // type:object size:0x1 data:byte +sId__Q23EGG10G3DUtility = .sbss:0x80576820; // type:object size:0x1 data:byte sAllocator__Q23EGG10G3DUtility = .sbss:0x80576824; // type:object size:0x4 data:4byte -lbl_80576828 = .sbss:0x80576828; // type:object size:0x4 data:4byte -lbl_8057682C = .sbss:0x8057682C; // type:object size:0x4 data:4byte -lbl_80576830 = .sbss:0x80576830; // type:object size:0x8 data:4byte +sBuf__Q23EGG10G3DUtility = .sbss:0x80576828; // type:object size:0x4 data:4byte +sOffset__Q23EGG10G3DUtility = .sbss:0x8057682C; // type:object size:0x4 data:4byte +sSize__Q23EGG10G3DUtility = .sbss:0x80576830; // type:object size:0x8 data:4byte spScreen__Q23EGG15GlobalDrawState = .sbss:0x80576838; // type:object size:0x4 data:4byte sCameraId__Q23EGG15GlobalDrawState = .sbss:0x8057683C; // type:object size:0x2 data:2byte sDrawFlag__Q23EGG15GlobalDrawState = .sbss:0x80576840; // type:object size:0x4 data:4byte diff --git a/include/egg/gfx/eggG3DUtility.h b/include/egg/gfx/eggG3DUtility.h index 7ad5a736..df570020 100644 --- a/include/egg/gfx/eggG3DUtility.h +++ b/include/egg/gfx/eggG3DUtility.h @@ -1,6 +1,7 @@ #ifndef EGG_G3D_UTILITY_H #define EGG_G3D_UTILITY_H +#include "egg/egg_types.h" #include "nw4r/g3d/g3d_scnmdl.h" #include "nw4r/g3d/res/g3d_resmat.h" #include "nw4r/math/math_types.h" @@ -20,23 +21,41 @@ public: /* 0x03 */ s8 texCoordId; }; - static u32 SetTexture( - nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *param_2, const char *name, GXTexObj *texObj, - bool copy, SetTextureResult *pResult, int param_7, int param_8 + struct SearchResult { + /* 0x00 */ u16 nodeIdx; + /* 0x04 */ const char *name; + }; + + static u16 SetTexture( + nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *param_2, const char *name, const GXTexObj *texObj, + bool copy, SetTextureResult *pResult, int maxNumResults, int param_8 ); - static void setUpLightSet(nw4r::g3d::LightSetting &, nw4r::g3d::ResAnmScn, int); + static int ApplyLightMat(nw4r::g3d::ResMdl mdl, const char *prefix); - static nw4r::math::MTX34 *GetWorldMtxArray(int, int); + static bool setUpLightSet(nw4r::g3d::LightSetting &, nw4r::g3d::ResAnmScn, int); - static int searchStringResNode(nw4r::g3d::ResMdl, const char *, u16 *, u32); - static int searchStringResMat(nw4r::g3d::ResMdl, const char *, u16 *, u32); - static int searchStringResTexPlttInfo(nw4r::g3d::ResMdl, const char *, u16 *, u32); + static void *BumpAlloc(u32 size, u32 align); + static void ResetBumpAlloc() { + sOffset = 0; + } - typedef int (*MdlSearch)(nw4r::g3d::ResMdl, const char *, u16 *, u32); + static void create(u32 size, Heap *pHeap); + + static int searchStringResNode(nw4r::g3d::ResMdl mdl, const char * name, bool exactMatch, SearchResult *pResults, int maxNumResults); + static int searchStringResMat(nw4r::g3d::ResMdl mdl, const char * name, bool exactMatch, SearchResult *pResults, int maxNumResults); + static int searchStringResTexPlttInfo(nw4r::g3d::ResMdl mdl, const char * name, bool exactMatch, SearchResult *pResults, int maxNumResults); + + typedef int (*MdlSearch)(nw4r::g3d::ResMdl mdl, const char * name, bool exactMatch, SearchResult *pResults, int maxNumResults); private: + static void defaultTexMtxFunc(nw4r::math::MTX34 *pMtx, s8 camRef, s8 lightRef); + static MEMAllocator *sAllocator; + static void *sBuf; + static u32 sSize; + static u32 sOffset; + static u8 sId; }; } // namespace EGG diff --git a/include/egg/gfx/eggLightTextureMgr.h b/include/egg/gfx/eggLightTextureMgr.h index 86400aa1..c12fc011 100644 --- a/include/egg/gfx/eggLightTextureMgr.h +++ b/include/egg/gfx/eggLightTextureMgr.h @@ -30,8 +30,8 @@ public: bool setBinaryToTexture(const void *data); bool deleteTexture(int idx); - int replaceModelTextures(nw4r::g3d::ResMdl) const; - int replaceModelTexture(int, nw4r::g3d::ResMdl) const; + u16 replaceModelTextures(nw4r::g3d::ResMdl) const; + u16 replaceModelTexture(int, nw4r::g3d::ResMdl) const; void drawAndCaptureTexture(f32, f32, f32, f32); void frameReset(); void correctLightObject(); diff --git a/include/nw4r/g3d/res/g3d_resmat.h b/include/nw4r/g3d/res/g3d_resmat.h index 9a110ba5..0b7ddc59 100644 --- a/include/nw4r/g3d/res/g3d_resmat.h +++ b/include/nw4r/g3d/res/g3d_resmat.h @@ -246,6 +246,13 @@ public: ); } + void Disable(u32 id) { + ref().flag = + ref().flag & + ~((TexSrt::FLAG_ANM_EXISTS | TexSrt::FLAG_SCALE_ONE | TexSrt::FLAG_ROT_ZERO | TexSrt::FLAG_TRANS_ZERO) + << (id * TexSrt::NUM_OF_FLAGS)); + } + bool IsExist(u32 id) const { if (IsValid()) { return ptr()->flag & (1 << id * TexSrt::NUM_OF_FLAGS); @@ -513,6 +520,35 @@ private: void BindPltt_(const ResPltt pltt, ResTlutObj tlutObj); }; +/****************************************************************************** + * + * ResTexPlttInfoOffsetData + * + ******************************************************************************/ +struct ResTexPlttInfoOffsetData { + u32 size; // at 0x0 + u8 _0x04[4]; // at 0x4 + struct Unk { + s32 texPlltInfo; + u8 _0x00[4]; + } data[1]; // at 0x8 +}; + +class ResTexPlttInfoOffset : public ResCommon { +public: + NW4R_G3D_RESOURCE_FUNC_DEF(ResTexPlttInfoOffset); + + ResTexPlttInfo GetPllt(int idx) const { + const ResTexPlttInfoOffsetData &r = ref(); + return ofs_to_obj(r.data[idx].texPlltInfo); + } + + u32 GetNumData() const { + const ResTexPlttInfoOffsetData &r = ref(); + return r.size; + } +}; + /****************************************************************************** * * ResMatFur diff --git a/include/nw4r/g3d/res/g3d_resmdl.h b/include/nw4r/g3d/res/g3d_resmdl.h index 3d38c6ce..db0a2b6a 100644 --- a/include/nw4r/g3d/res/g3d_resmdl.h +++ b/include/nw4r/g3d/res/g3d_resmdl.h @@ -196,7 +196,7 @@ public: ResShp GetResShp(u32 idx) const; u32 GetResShpNumEntries() const; - ResTexPlttInfo GetResTexPlttInfoOffsetFromTexName(int idx) const; + ResTexPlttInfoOffset GetResTexPlttInfoOffsetFromTexName(int idx) const; u32 GetResTexPlttInfoOffsetFromTexNameNumEntries() const; ResMdlInfo GetResMdlInfo() { diff --git a/include/nw4r/g3d/res/g3d_resnode.h b/include/nw4r/g3d/res/g3d_resnode.h index 29242792..bc084e72 100644 --- a/include/nw4r/g3d/res/g3d_resnode.h +++ b/include/nw4r/g3d/res/g3d_resnode.h @@ -67,8 +67,8 @@ struct ResNodeData : ResNodeDataTypedef { math::_VEC3 scale; // at 0x20 math::_VEC3 rot; // at 0x2C math::_VEC3 translate; // at 0x38 - math::_VEC3 volume_min; // at 0x44 - math::_VEC3 volume_max; // at 0x50 + math::_VEC3 volume_min; // at 0x44 + math::_VEC3 volume_max; // at 0x50 s32 toParentNode; // at 0x5C s32 toChildNode; // at 0x60 s32 toNextSibling; // at 0x64 @@ -95,6 +95,11 @@ public: return ResName(NULL); } + const char *GetName() const { + const ResNodeData &r = ref(); + return ofs_to_ptr(r.name); + } + u32 GetID() const { if (IsValid()) { return ptr()->id; @@ -145,12 +150,12 @@ public: // not in the dwarf const math::VEC3 &GetBoundsMin() const { - return *(const math::VEC3*)&ref().volume_min; + return *(const math::VEC3 *)&ref().volume_min; } // not in the dwarf const math::VEC3 &GetBoundsMax() const { - return *(const math::VEC3*)&ref().volume_max; + return *(const math::VEC3 *)&ref().volume_max; } ResNode GetParentNode() { diff --git a/include/rvl/GX/GXTexture.h b/include/rvl/GX/GXTexture.h index c35865a0..e6428e51 100644 --- a/include/rvl/GX/GXTexture.h +++ b/include/rvl/GX/GXTexture.h @@ -44,6 +44,9 @@ void GXGetTexObjLODAll( u8 *biasClampEnable, u8 *edgeLODEnable, GXAnisotropy *anisotropy ); +void GXInitTexObjFilter(GXTexObj *, GXTexFilter minFilter, GXTexFilter magFilter); +void GXInitTexObjWrapMode(GXTexObj *, GXTexWrapMode wrapS, GXTexWrapMode wrapT); + void GXSetTexCoordScaleManually(GXTexCoordID, GXBool, u16, u16); void GXSetTexCoordBias(GXTexCoordID, GXBool, GXBool); diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring index 8b388ec0..8a62a363 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/cstring @@ -19,7 +19,7 @@ using ::strlen; using ::strncat; using ::strncmp; using ::strncpy; -// using ::strstr; +using ::strstr; } // namespace std #endif diff --git a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h index 86c421b3..8e36bf83 100644 --- a/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h +++ b/src/PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Include/string.h @@ -17,6 +17,7 @@ char *strrchr(const char *str, int c); char *strchr(const char *str, int c); int strncmp(const char *str1, const char *str2, size_t n); int strcmp(const char *str1, const char *str2); +char *strstr(const char *str1, const char *str2); char *strncat(char *dst, const char *src, size_t n); char *strcat(char *dst, const char *src); char *strncpy(char *dst, const char *src, size_t n); diff --git a/src/egg/gfx/eggG3DUtility.cpp b/src/egg/gfx/eggG3DUtility.cpp index b8da6920..a61cefc6 100644 --- a/src/egg/gfx/eggG3DUtility.cpp +++ b/src/egg/gfx/eggG3DUtility.cpp @@ -1,3 +1,379 @@ #include "egg/gfx/eggG3DUtility.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggHeap.h" +#include "nw4r/g3d/g3d_light.h" +#include "nw4r/g3d/g3d_state.h" +#include "nw4r/g3d/res/g3d_resanmamblight.h" +#include "nw4r/g3d/res/g3d_resanmlight.h" +#include "nw4r/g3d/res/g3d_resanmscn.h" +#include "nw4r/g3d/res/g3d_reslightset.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/g3d/res/g3d_resnode.h" +#include "nw4r/g3d/res/g3d_restev.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" + +#include + +namespace EGG { + +void G3DUtility::create(u32 size, Heap *pHeap) { + if (pHeap == nullptr) { + pHeap = Heap::getCurrentHeap(); + } + + if (size != 0) { + sBuf = operator new[](size, pHeap, 0x20); + sSize = size; + } else { + sBuf = nullptr; + sSize = 0; + } + + sOffset = 0; + + nw4r::g3d::G3DState::ScnDependentTexMtxFuncPtr pFunc; + u32 id = 5; + while (true) { + if (nw4r::g3d::G3DState::GetScnDependentTexMtxFunc(id, &pFunc, nullptr) && pFunc == defaultTexMtxFunc) { + break; + } + id++; + if (id >= 256) { + id = 5; + nw4r::g3d::G3DState::ScnDependentTexMtxFuncPtr pFunc2; + while (true) { + if (nw4r::g3d::G3DState::GetScnDependentTexMtxFunc(id, &pFunc2, nullptr) && + pFunc2 == nw4r::g3d::detail::ScnDependentMtxFunc::DefaultMapping) { + sId = id; + nw4r::g3d::G3DState::SetScnDependentTexMtxFunc( + id, defaultTexMtxFunc, nw4r::g3d::G3DState::SCNDEPENDENT_TEXMTX_FUNCTYPE_SRC_POS + ); + break; + } + id++; + if (id >= 256) { + break; + } + } + return; + } + } +} + +void G3DUtility::defaultTexMtxFunc(nw4r::math::MTX34 *pMtx, s8 camRef, s8 lightRef) { + const nw4r::math::MTX34 *mtxPtr = nw4r::g3d::G3DState::GetInvCameraMtxPtr(); + PSMTXCopy(mtxPtr->m, pMtx->m); +} + +bool G3DUtility::setUpLightSet(nw4r::g3d::LightSetting &lightSet, nw4r::g3d::ResAnmScn scn, int refNumber) { + if (!scn.IsValid()) { + return false; + } + + int end = scn.GetResLightSetMaxRefNumber() < lightSet.GetNumLightSet() ? scn.GetResLightSetMaxRefNumber() : + lightSet.GetNumLightSet(); + int start = 0; + if (refNumber >= 0) { + start = refNumber; + end = refNumber + 1; + } + + for (; start < end; start++) { + nw4r::g3d::LightSet set = lightSet.GetLightSet(start); + nw4r::g3d::ResLightSet resSet = scn.GetResLightSetByRefNumber(start); + + if (!set.IsValid()) { + return false; + } + + if (resSet.IsValid()) { + u32 counter = 7; + u32 j = 0; + u32 numLight = resSet.GetNumLight(); + if (numLight != 0) { + for (; j < numLight; j++) { + if (resSet.GetLightID(j) != 0xFFFF) { + nw4r::g3d::ResAnmLight anmLight = scn.GetResAnmLight(resSet.GetLightID(j)); + set.SelectLightObj(j, anmLight.GetRefNumber()); + if (anmLight.HasSpecularLight()) { + set.SelectLightObj(counter--, anmLight.GetSpecularLightIdx()); + } + } else { + set.SelectLightObj(j, -1); + } + } + } + + for (; numLight <= counter; numLight++) { + set.SelectLightObj(numLight, -1); + } + + if (resSet.HasAmbLight()) { + nw4r::g3d::ResAnmAmbLight anmAmbLight = scn.GetResAnmAmbLight(resSet.GetAmbLightID()); + set.SelectAmbLightObj(anmAmbLight.GetRefNumber()); + } else { + set.SelectAmbLightObj(-1); + } + } + } + + return true; +} + +inline bool searchInner( + const char *name, const char *candidate, bool exactMatch, G3DUtility::SearchResult *pResults, int i, int resultIdx, + int maxNumResults +) { + if (name != nullptr) { + bool found; + if (exactMatch) { + found = !std::strcmp(candidate, name); + } else { + found = std::strstr(candidate, name); + } + if (!found) { + goto err; + } + } + + if (resultIdx < maxNumResults) { + pResults[resultIdx].nodeIdx = i; + pResults[resultIdx].name = candidate; + } + return true; + +err: + return false; +} + +int G3DUtility::searchStringResNode( + nw4r::g3d::ResMdl mdl, const char *name, bool exactMatch, SearchResult *pResults, int maxNumResults +) { + u16 resultIdx = 0; + for (int i = 0; i < mdl.GetResNodeNumEntries(); i++) { + nw4r::g3d::ResNode nd = mdl.GetResNode(i); + const char *nodeName = nd.GetName(); + + if (searchInner(name, nodeName, exactMatch, pResults, i, resultIdx, maxNumResults)) { + resultIdx++; + } + } + + return resultIdx; +} + +int G3DUtility::searchStringResMat( + nw4r::g3d::ResMdl mdl, const char *name, bool exactMatch, SearchResult *pResults, int maxNumResults +) { + u16 resultIdx = 0; + for (int i = 0; i < mdl.GetResMatNumEntries(); i++) { + nw4r::g3d::ResMat mat = mdl.GetResMat(i); + const char *nodeName = mat.GetName(); + + if (searchInner(name, nodeName, exactMatch, pResults, i, resultIdx, maxNumResults)) { + resultIdx++; + } + } + + return resultIdx; +} + +int G3DUtility::searchStringResTexPlttInfo( + nw4r::g3d::ResMdl mdl, const char *name, bool exactMatch, SearchResult *pResults, int maxNumResults +) { + u16 resultIdx = 0; + for (u32 i = 0; i < mdl.GetResTexPlttInfoOffsetFromTexNameNumEntries(); i++) { + nw4r::g3d::ResTexPlttInfoOffset info = mdl.GetResTexPlttInfoOffsetFromTexName(i); + for (u16 j = 0; j < info.GetNumData(); j++) { + const char *nodeName = info.GetPllt(j).GetTexName(); + if (searchInner(name, nodeName, exactMatch, pResults, i, resultIdx, maxNumResults)) { + resultIdx++; + } + } + } + + return resultIdx; +} + +u16 G3DUtility::SetTexture( + nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *matAccess, const char *name, const GXTexObj *texObj, + bool copy, SetTextureResult *pResult, int maxNumResults, int param_8 +) { + if (!resMat.IsValid()) { + return 0; + } + + u16 resultIdx = 0; + for (u16 i = 0; i < resMat.GetNumResTexPlttInfo(); i++) { + nw4r::g3d::ResTexPlttInfo plltInfo = resMat.GetResTexPlttInfo(i); + const char *plltName = plltInfo.GetTexName(); + if (std::strcmp(name, plltName)) { + continue; + } + for (int j = 0; j < 2; j++) { + nw4r::g3d::ResTexObj resTexObj(nullptr); + if (j == 0) { + if ((matAccess == nullptr || param_8 == 1) || + (param_8 == 0 && !matAccess->GetResTexObj(false).IsValid())) { + resTexObj = resMat.GetResTexObj(); + } + } else if (matAccess != nullptr) { + resTexObj = param_8 == 0 ? matAccess->GetResTexObjEx() : matAccess->GetResTexObj(param_8 == 3); + } + + if (resTexObj.IsValid()) { + GXTexObj *obj = resTexObj.GetTexObj(plltInfo.ref().mapID); + if (copy) { + void *pImage; + u16 width; + u16 height; + GXTexFmt format; + GXTexWrapMode wrapS; + GXTexWrapMode wrapT; + u8 mipmap; + GXGetTexObjAll(obj, &pImage, &width, &height, &format, &wrapS, &wrapT, &mipmap); + + GXTexFilter minFilter; + GXTexFilter magFilter; + f32 minLOD; + f32 maxLOD; + f32 LODBias; + u8 biasClampEnable; + u8 edgeLODEnable; + GXAnisotropy anisotropy; + GXGetTexObjLODAll( + obj, &minFilter, &magFilter, &minLOD, &maxLOD, &LODBias, &biasClampEnable, &edgeLODEnable, + &anisotropy + ); + + *obj = *texObj; + GXInitTexObjFilter(obj, minFilter, magFilter); + GXInitTexObjWrapMode(obj, wrapS, wrapT); + } else { + *obj = *texObj; + } + } + } + + if (pResult != nullptr && resultIdx < maxNumResults) { + pResult[resultIdx].texCoordId = -1; + pResult[resultIdx].texMapId = -1; + + nw4r::g3d::ResTev resTev = resMat.GetResTev(); + for (u8 stage = 0; stage < resTev.GetNumTevStages(); stage++) { + GXTexCoordID coord; + GXTexMapID map; + if (resTev.GXGetTevOrder(static_cast(stage), &coord, &map, nullptr) && + map == plltInfo.ref().mapID) { + pResult[resultIdx].texMapId = map; + pResult[resultIdx].texCoordId = coord; + } + } + } + resultIdx++; + } + + return resultIdx; +} + +int G3DUtility::ApplyLightMat(nw4r::g3d::ResMdl mdl, const char *prefix) { + GXTexCoordID matchingLayerCoords[8]; + + int prefixLen = std::strlen(prefix); + int result = 0; + + u32 i = 0; + u32 numMats = mdl.GetResMatNumEntries(); + if (numMats != 0) { + for (; i < numMats; i++) { + int numMatchingLayers = 0; + nw4r::g3d::ResMat mat = mdl.GetResMat(i); + if (mat.GetResGenMode().GXGetNumTexGens() >= mat.GetNumResTexPlttInfo()) { + for (u32 j = 0; j < mat.GetNumResTexPlttInfo(); j++) { + const char *texName = mat.GetResTexPlttInfo(j).GetTexName(); + bool prefixMatch = true; + int rem = prefixLen; + for (int i = 0; i < prefixLen; i++) { + if (prefix[i] != texName[i]) { + prefixMatch = false; + break; + } + } + if (prefixMatch) { + matchingLayerCoords[numMatchingLayers++] = static_cast(j); + } + } + + if (numMatchingLayers > 1) { + nw4r::g3d::ResGenMode genMode = mat.GetResGenMode(); + int numTexGens = genMode.GXGetNumTexGens(); + nw4r::g3d::ResMatTexCoordGen resMatTexCoordGen = mat.GetResMatTexCoordGen(); + nw4r::g3d::ResTexSrt resTexSrt = mat.GetResTexSrt(); + nw4r::g3d::ResTev resTev = mat.GetResTev(); + GXTexGenType texGenType; + GXTexGenSrc param; + GXBool normalize; + u32 postMtx; + resMatTexCoordGen.GXGetTexCoordGen2( + matchingLayerCoords[0], &texGenType, ¶m, &normalize, &postMtx + ); + numMatchingLayers--; + for (; numMatchingLayers > 0; numMatchingLayers--) { + GXTexCoordID idx = matchingLayerCoords[numMatchingLayers]; + if (idx == numTexGens - 1) { + u32 numStages = resTev.GetNumTevStages(); + for (u32 stage = 0; stage < numStages; stage++) { + GXTexCoordID coord; + GXTexMapID map; + GXChannelID channel; + if (resTev.GXGetTevOrder(static_cast(stage), &coord, &map, &channel) && + coord == idx) { + resTev.GXSetTevOrder( + static_cast(stage), + matchingLayerCoords[0], map, channel + ); + } + } + + int stage = 0; + int nInds = genMode.GXGetNumIndStages(); + for (; stage < nInds; stage++) { + GXTexCoordID coord; + GXTexMapID map; + if (resTev.GXGetIndTexOrder(static_cast(stage), &coord, &map) && + coord == idx) { + resTev.GXSetIndTexOrder( + static_cast(stage), + static_cast(matchingLayerCoords[0]), map + ); + } + } + resMatTexCoordGen.Disable(idx); + result++; + resTexSrt.Disable(idx); + numTexGens--; + } + } + resMatTexCoordGen.DCStore(false); + resTev.DCStore(false); + genMode.GXSetNumTexGens(numTexGens); + } + } + } + } + + return result; +} + +void *G3DUtility::BumpAlloc(u32 size, u32 align) { + u32 next = sOffset % align != 0 ? sOffset + (align - sOffset % align) : sOffset; + sOffset = next + size; + // REGSWAP + return reinterpret_cast(sBuf) + next; +} + +} // namespace EGG diff --git a/src/egg/gfx/eggLightTextureMgr.cpp b/src/egg/gfx/eggLightTextureMgr.cpp index b1aa0cee..4acbff26 100644 --- a/src/egg/gfx/eggLightTextureMgr.cpp +++ b/src/egg/gfx/eggLightTextureMgr.cpp @@ -106,15 +106,15 @@ bool LightTextureManager::deleteTexture(int idx) { return false; } -int LightTextureManager::replaceModelTextures(nw4r::g3d::ResMdl mdl) const { - int count = 0; +u16 LightTextureManager::replaceModelTextures(nw4r::g3d::ResMdl mdl) const { + u16 count = 0; for (u16 i = 0; i < mTextureCount; i++) { count += replaceModelTexture(i, mdl); } return count; } -int LightTextureManager::replaceModelTexture(int tex, nw4r::g3d::ResMdl mdl) const { +u16 LightTextureManager::replaceModelTexture(int tex, nw4r::g3d::ResMdl mdl) const { if (mpTextures[tex] == nullptr) { return 0; } @@ -122,12 +122,12 @@ int LightTextureManager::replaceModelTexture(int tex, nw4r::g3d::ResMdl mdl) con G3DUtility::SetTextureResult buf[256]; GXTexObj obj; mpTextures[tex]->getTexObj(&obj); - int count = 0; + u16 count = 0; for (int i = 0; i < mdl.GetResMatNumEntries(); i++) { nw4r::g3d::ResMat mat = mdl.GetResMat(i); - int res = G3DUtility::SetTexture(mat, nullptr, mpTextures[tex]->getName(), &obj, false, buf, 0xFF, 2); - for (int j = 0; j < (u16)res; j++) { + u16 res = G3DUtility::SetTexture(mat, nullptr, mpTextures[tex]->getName(), &obj, false, buf, 0xFF, 2); + for (int j = 0; j < res; j++) { if (buf[j].texCoordId != -1) { fn_804AE340(mat, static_cast(buf[j].texCoordId)); } diff --git a/src/egg/gfx/eggModelEx.cpp b/src/egg/gfx/eggModelEx.cpp index daa9d196..14c10293 100644 --- a/src/egg/gfx/eggModelEx.cpp +++ b/src/egg/gfx/eggModelEx.cpp @@ -46,7 +46,7 @@ static const G3DUtility::MdlSearch sMdlSearch[6] = { }; void thisProbablyGotDeadStripped() { - sMdlSearch[0](g3d::ResMdl(nullptr), "", nullptr, 0); + sMdlSearch[0](g3d::ResMdl(nullptr), "", false, nullptr, 0); } extern "C" s32 lbl_8057682C; @@ -57,11 +57,14 @@ void ModelEx::getShapeMinMax(u16 shapeIndex, math::VEC3 *pMin, math::VEC3 *pMax, case cType_ScnMdl: case cType_ScnMdl1Mat1Shp: { g3d::ResShp shp = getResShp(shapeIndex); - lbl_8057682C = 0; + + G3DUtility::ResetBumpAlloc(); + g3d::ResMdl mdl = getResMdl(); math::MTX34 tmpMtx; g3d::ResMdlInfo info = mdl.GetResMdlInfo(); - math::MTX34 *pMtxArr = G3DUtility::GetWorldMtxArray(info.GetNumPosNrmMtx() * sizeof(math::MTX34), 1); + math::MTX34 *pMtxArr = + reinterpret_cast(G3DUtility::BumpAlloc(info.GetNumPosNrmMtx() * sizeof(math::MTX34), 1)); if (doCalcWorld) { PSMTXIdentity(tmpMtx); calcWorld(pMtxArr, &tmpMtx); @@ -92,7 +95,7 @@ void ModelEx::getShapeMinMax(u16 shapeIndex, math::VEC3 *pMin, math::VEC3 *pMax, math::VEC3Maximize(pMax, pMax, &tmpVec); } } - lbl_8057682C = 0; + G3DUtility::ResetBumpAlloc(); break; } case cType_ScnProcModel: diff --git a/src/nw4r/g3d/res/g3d_resmdl.cpp b/src/nw4r/g3d/res/g3d_resmdl.cpp index 1e49d94e..145b525b 100644 --- a/src/nw4r/g3d/res/g3d_resmdl.cpp +++ b/src/nw4r/g3d/res/g3d_resmdl.cpp @@ -1,4 +1,5 @@ #include "nw4r/g3d.h" // IWYU pragma: export +#include "nw4r/g3d/res/g3d_resmat.h" namespace nw4r { namespace g3d { @@ -192,8 +193,8 @@ u32 ResMdl::GetResShpNumEntries() const { * ResTexPlttInfo * ******************************************************************************/ -ResTexPlttInfo ResMdl::GetResTexPlttInfoOffsetFromTexName(int idx) const { - return ResTexPlttInfo(ofs_to_obj(ref().toResTexNameToTexPlttInfoDic)[idx]); + ResTexPlttInfoOffset ResMdl::GetResTexPlttInfoOffsetFromTexName(int idx) const { + return ResTexPlttInfoOffset(ofs_to_obj(ref().toResTexNameToTexPlttInfoDic)[idx]); } u32 ResMdl::GetResTexPlttInfoOffsetFromTexNameNumEntries() const { diff --git a/src/toBeSorted/arc_callback_handler.cpp b/src/toBeSorted/arc_callback_handler.cpp index f2016729..aca65dd4 100644 --- a/src/toBeSorted/arc_callback_handler.cpp +++ b/src/toBeSorted/arc_callback_handler.cpp @@ -1,6 +1,7 @@ #include "d/col/bg/d_bg_s.h" #include "d/col/bg/d_bg_w_kcol.h" #include "d/d_rawarchive.h" +#include "egg/gfx/eggG3DUtility.h" #include "egg/gfx/eggLightTextureMgr.h" #include "egg/gfx/eggLightManager.h" #include "m/m3d/m3d.h" @@ -16,8 +17,6 @@ ArcCallbackHandler ArcCallbackHandler::sInstance; #define NAME_OARC 'oarc' #define NAME_RARC 'rarc' -extern "C" void FUN_804a7260(nw4r::g3d::ResMdl, const char *prefix); - void BindSystemModelsAndLighting(nw4r::g3d::ResFile file) { nw4r::g3d::ResFile sysFile(OarcManager::GetInstance()->getMdlFromArc2("System")); if (sysFile.IsValid()) { @@ -30,7 +29,7 @@ void BindSystemModelsAndLighting(nw4r::g3d::ResFile file) { for (int i = 0; i < file.GetResMdlNumEntries(); i++) { nw4r::g3d::ResMdl mdl = file.GetResMdl(i); lightTexMgr->replaceModelTextures(mdl); - FUN_804a7260(mdl, "Lm"); + EGG::G3DUtility::ApplyLightMat(mdl, "Lm"); for (int j = 0; j < mdl.GetResMatNumEntries(); j++) { nw4r::g3d::ResMat mat = mdl.GetResMat(j); if (mat.IsOpaque()) { From b6db4eb1005d7daf4d5f235a7f5b140e411856c4 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 28 Mar 2025 18:59:44 +0100 Subject: [PATCH 52/62] GfxEngine OK --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 2 +- configure.py | 2 +- include/egg/gfx/eggGfxEngine.h | 2 +- src/egg/gfx/eggGfxEngine.cpp | 37 +++++++++++++++++++++++++++++++++- 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index edcd20d2..03669cd1 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2242,6 +2242,7 @@ egg/gfx/eggG3DUtility.cpp: egg/gfx/eggGfxEngine.cpp: .text start:0x804A75B0 end:0x804A7744 + .data start:0x8056F048 end:0x8056F058 egg/gfx/eggGlobalDrawState.cpp: .text start:0x804A7750 end:0x804A7814 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 560bd020..7f9823ab 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -37367,7 +37367,7 @@ __vt__Q23EGG16DrawPathLightMap = .data:0x8056EFA0; // type:object size:0x50 __vt__Q23EGG3Fog = .data:0x8056EFF0; // type:object size:0x20 __vt__Q23EGG10FogManager = .data:0x8056F010; // type:object size:0x1C __vt__Q23EGG7Frustum = .data:0x8056F030; // type:object size:0x14 -EGG__GfxEnginer__Configuration__vtable = .data:0x8056F048; // type:object size:0x10 +__vt__Q33EGG9GfxEngine13Configuration = .data:0x8056F048; // type:object size:0xC __vt__Q23EGG8IScnProc = .data:0x8056F058; // type:object size:0x10 __vt__Q23EGG12LightManager = .data:0x8056F068; // type:object size:0x2C __vt__Q23EGG11LightObject = .data:0x8056F098; // type:object size:0x20 diff --git a/configure.py b/configure.py index c8b73a79..8b0a546e 100644 --- a/configure.py +++ b/configure.py @@ -880,7 +880,7 @@ config.libs = [ Object(Matching, "egg/gfx/eggFogManager.cpp"), Object(NonMatching, "egg/gfx/eggFrustum.cpp"), Object(NonMatching, "egg/gfx/eggG3DUtility.cpp"), - Object(NonMatching, "egg/gfx/eggGfxEngine.cpp"), + Object(Matching, "egg/gfx/eggGfxEngine.cpp"), Object(Matching, "egg/gfx/eggGlobalDrawState.cpp"), Object(NonMatching, "egg/gfx/eggGXUtility.cpp"), Object(Matching, "egg/gfx/eggIScnProc.cpp"), diff --git a/include/egg/gfx/eggGfxEngine.h b/include/egg/gfx/eggGfxEngine.h index 20b6729b..cd1a88ef 100644 --- a/include/egg/gfx/eggGfxEngine.h +++ b/include/egg/gfx/eggGfxEngine.h @@ -18,7 +18,7 @@ struct Configuration { /* 0x10 */ u32 bufferSize; /* 0x14 */ u16 field_0x14; /* 0x16 */ u16 field_0x16; - /* 0x18 */ u8 UNK_0x18[4]; + /* 0x18 */ u8 field_0x18; Configuration(); virtual ~Configuration() {} }; diff --git a/src/egg/gfx/eggGfxEngine.cpp b/src/egg/gfx/eggGfxEngine.cpp index 7a2da6a7..9a1fc150 100644 --- a/src/egg/gfx/eggGfxEngine.cpp +++ b/src/egg/gfx/eggGfxEngine.cpp @@ -1,3 +1,38 @@ #include "egg/gfx/eggGfxEngine.h" -namespace EGG {} // namespace EGG +#include "common.h" +#include "egg/core/eggDisplay.h" +#include "egg/core/eggSystem.h" +#include "egg/core/eggVideo.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +// Needed for dtor placement +void ProbablySomethingCreatingThisConfiguration() { + GfxEngine::Configuration c; +} + +GfxEngine::Configuration::Configuration() + : efbWidth(640), + efbHeight(528), + clearColor((GXColor){0, 0, 0, 0}), + field_0x08(0), + field_0x0C(32), + field_0x0E(256), + bufferSize(0), + field_0x14(608), + field_0x16(812), + field_0x18(0) { + if (BaseSystem::getVideo() != nullptr) { + efbWidth = BaseSystem::getVideo()->pRenderMode->fbWidth; + efbHeight = BaseSystem::getVideo()->pRenderMode->efbHeight; + } + if (BaseSystem::getDisplay() != nullptr) { + clearColor = BaseSystem::getDisplay()->getClearColor(); + } + bufferSize = GXGetTexBufferSize(efbWidth, efbHeight, GX_TF_RGBA8, false, 0) * 3; +} + +} // namespace EGG From 2d95f92cfec09e95cd6e559e9c76a23110376205 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 28 Mar 2025 20:22:57 +0100 Subject: [PATCH 53/62] GXUtility has one weird issue --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 2 +- include/egg/gfx/eggGXUtility.h | 7 ++- src/egg/gfx/eggGXUtility.cpp | 85 +++++++++++++++++++++++++++++++++- 4 files changed, 91 insertions(+), 4 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 03669cd1..f4ce347e 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2252,6 +2252,7 @@ egg/gfx/eggGlobalDrawState.cpp: egg/gfx/eggGXUtility.cpp: .text start:0x804A7820 end:0x804A7BC0 + .sdata2 start:0x8057F640 end:0x8057F678 egg/gfx/eggIScnProc.cpp: .text start:0x804A7BC0 end:0x804A7F7C diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 7f9823ab..81f62ff6 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -48096,7 +48096,7 @@ lbl_8057F62C = .sdata2:0x8057F62C; // type:object size:0x4 data:float lbl_8057F630 = .sdata2:0x8057F630; // type:object size:0x4 data:float lbl_8057F634 = .sdata2:0x8057F634; // type:object size:0x4 data:float lbl_8057F638 = .sdata2:0x8057F638; // type:object size:0x4 data:float -EGG__GXUtility__sTexMtxIDs = .sdata2:0x8057F640; // type:object size:0x8 +s_texMtxIds__Q23EGG9GXUtility = .sdata2:0x8057F640; // type:object size:0x8 lbl_8057F648 = .sdata2:0x8057F648; // type:object size:0x4 data:float lbl_8057F64C = .sdata2:0x8057F64C; // type:object size:0x4 data:float lbl_8057F650 = .sdata2:0x8057F650; // type:object size:0x4 data:float diff --git a/include/egg/gfx/eggGXUtility.h b/include/egg/gfx/eggGXUtility.h index cba929e6..f85f56e0 100644 --- a/include/egg/gfx/eggGXUtility.h +++ b/include/egg/gfx/eggGXUtility.h @@ -12,11 +12,14 @@ namespace EGG { class GXUtility { public: static int getTexMtxID(int); - static void getTexObj(GXTexObj *, const EGG::ResTIMG &); + static void setScaleOffsetPerspective(f32*, f32, f32, f32, f32); + static void getTexObj(GXTexObj *, const ResTIMG &); static void getTexObj(GXTexObj *, nw4r::g3d::ResTex, GXTexWrapMode, GXTexWrapMode, GXTexFilter, GXTexFilter); static void getNormalColor(GXColor &outColor, const Vector3f &vec); - static void setScaleOffsetPerspective(f32*, f32, f32, f32, f32); + +private: + static const u8 s_texMtxIds[8]; }; } // namespace EGG diff --git a/src/egg/gfx/eggGXUtility.cpp b/src/egg/gfx/eggGXUtility.cpp index 43963b51..09f0390c 100644 --- a/src/egg/gfx/eggGXUtility.cpp +++ b/src/egg/gfx/eggGXUtility.cpp @@ -1,3 +1,86 @@ #include "egg/gfx/eggGXUtility.h" -namespace EGG {} // namespace EGG +#include "egg/gfx/eggTexture.h" +#include "rvl/GX/GXTexture.h" +#include "rvl/GX/GXTypes.h" + +namespace EGG { + +const u8 GXUtility::s_texMtxIds[8] = {30, 33, 36, 39, 42, 45, 48, 51}; + +int GXUtility::getTexMtxID(int idx) { + return s_texMtxIds[idx]; +} + +void GXUtility::setScaleOffsetPerspective(f32 *pOut, f32 f1, f32 f2, f32 f3, f32 f4) { + pOut[1] *= (1.0f / f1); + pOut[3] *= (1.0f / f2); + pOut[2] += f3; + pOut[4] += f4; +} + +void GXUtility::getTexObj(GXTexObj *obj, const ResTIMG &img) { + u32 offset = img.imageOffset != 0 ? img.imageOffset : sizeof(ResTIMG); + void *pImage = const_cast(reinterpret_cast(reinterpret_cast(&img) + offset)); + // Missing a redundant register move here (obj r30->r3) + GXInitTexObj( + obj, pImage, img.width, img.height, static_cast(img.format), static_cast(img.wrapS), + static_cast(img.wrapT), img.mipmapEnabled != 0 + ); + GXInitTexObjLOD( + obj, static_cast(img.minFilter), static_cast(img.magFilter), img.minLOD / 8.0f, + img.maxLOD / 8.0f, img.LODBias / 100.0f, img.biasClamp, img.doEdgeLOD, + static_cast(img.maxAnisotropy) + ); +} + +void GXUtility::getTexObj( + GXTexObj *obj, nw4r::g3d::ResTex resTex, GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXTexFilter minFilter, + GXTexFilter magFilter +) { + void *pTexData; + u16 width; + u16 height; + GXTexFmt format; + f32 minLod; + f32 maxLod; + GXBool mipMap; + if (resTex.GetTexObjParam(&pTexData, &width, &height, &format, &minLod, &maxLod, &mipMap)) { + GXInitTexObj(obj, pTexData, width, height, format, wrapS, wrapT, mipMap); + GXInitTexObjLOD(obj, minFilter, magFilter, minLod, maxLod, 0.0f, false, false, GX_ANISO_1); + } +} + +void GXUtility::getNormalColor(GXColor &outColor, const Vector3f &vec) { + // Are there inlines that might work here? Probably! + f32 fs[3]; + f32 g = vec.z < 0.0f ? vec.y * 128.0f + 128.0f - 0.5f : vec.z * 127.0f + 128.0f + 0.5f; + f32 b = vec.y < 0.0f ? vec.y * 128.0f + 128.0f - 0.5f : vec.y * 127.0f + 128.0f + 0.5f; + f32 a = vec.x < 0.0f ? vec.x * 128.0f + 128.0f - 0.5f : vec.x * 127.0f + 128.0f + 0.5f; + + fs[0] = a; + fs[1] = b; + fs[2] = g; + + if (fs[0] < 0.0f) { + fs[0] = 0.0f; + } else if (fs[0] > 255.0f) { + fs[0] = 255.0f; + } + if (fs[1] < 0.0f) { + fs[1] = 0.0f; + } else if (fs[1] > 255.0f) { + fs[1] = 255.0f; + } + if (fs[2] < 0.0f) { + fs[2] = 0.0f; + } else if (fs[2] > 255.0f) { + fs[2] = 255.0f; + } + + outColor.a = fs[0]; + outColor.b = fs[1]; + outColor.g = fs[2]; +} + +} // namespace EGG From 69ce14b38c62a04872fa2273268955b36a1c6b8e Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 28 Mar 2025 20:37:41 +0100 Subject: [PATCH 54/62] Work around LightTextureMgr regression --- include/egg/gfx/eggLightManager.h | 4 ++-- src/egg/gfx/eggLightTextureMgr.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/egg/gfx/eggLightManager.h b/include/egg/gfx/eggLightManager.h index c863cdc4..00aef3a4 100644 --- a/include/egg/gfx/eggLightManager.h +++ b/include/egg/gfx/eggLightManager.h @@ -85,11 +85,11 @@ public: return num < 8 ? num : 8; } - const LightObject *GetLightObject(u16 i) const { + const LightObject *GetLightObject(int i) const { return &mpLightData[i].mLightObject; } - LightObject *GetLightObject(u16 i) { + LightObject *GetLightObject(int i) { return &mpLightData[i].mLightObject; } diff --git a/src/egg/gfx/eggLightTextureMgr.cpp b/src/egg/gfx/eggLightTextureMgr.cpp index 4acbff26..17f28c6d 100644 --- a/src/egg/gfx/eggLightTextureMgr.cpp +++ b/src/egg/gfx/eggLightTextureMgr.cpp @@ -161,7 +161,7 @@ bool LightTextureManager::setBinaryToTexture(const void *data) { void LightTextureManager::correctLightObject() { int j = 0; for (int i = 0; i < mpLightMgr->GetNumLightData(); i++) { - const LightObject *o = mpLightMgr->GetLightObject(i); + const LightObject *o = mpLightMgr->GetLightObject((u16)i); if (o->CheckFlag1() && o->CheckFlag0x20()) { mpObjects[j] = o; j++; From 38deda681b3b2b1ed1b0327e3b501691029ccdb5 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 29 Mar 2025 21:19:37 +0100 Subject: [PATCH 55/62] Pretend to have given all files an honest attempt --- config/SOUE01/splits.txt | 6 +- config/SOUE01/symbols.txt | 48 +++--- include/egg/egg_types.h | 2 + include/egg/gfx/eggCapTexture.h | 1 + include/egg/gfx/eggDrawPathBloom.h | 57 ++++++- include/egg/gfx/eggDrawPathDOF.h | 38 ++++- include/egg/gfx/eggFrustum.h | 26 ++- include/egg/gfx/eggPostEffectBase.h | 15 +- include/egg/gfx/eggPostEffectBlur.h | 11 ++ include/egg/gfx/eggPostEffectMask.h | 8 + include/egg/gfx/eggPostEffectMaskDOF.h | 16 ++ include/egg/gfx/eggPostEffectSimple.h | 4 + include/egg/gfx/eggScreen.h | 8 + include/egg/gfx/eggStateEfb.h | 15 +- src/egg/gfx/eggCapTexture.cpp | 14 ++ src/egg/gfx/eggDrawPathBloom.cpp | 48 +++++- src/egg/gfx/eggDrawPathDOF.cpp | 214 ++++++++++++++++++++++++- 17 files changed, 491 insertions(+), 40 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index f4ce347e..e036519b 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2183,7 +2183,7 @@ egg/gfx/eggAnalizeDL.cpp: .sdata2 start:0x8057F3E0 end:0x8057F408 egg/gfx/eggCapTexture.cpp: - .text start:0x8049D7C0 end:0x8049D9C4 + .text start:0x8049D7C0 end:0x8049DA28 .rodata start:0x804FBA30 end:0x804FBA48 .data start:0x8056ED70 end:0x8056ED80 .sdata2 start:0x8057F410 end:0x8057F418 @@ -2210,10 +2210,14 @@ egg/gfx/eggDrawPathBase.cpp: egg/gfx/eggDrawPathBloom.cpp: .text start:0x804A0EA0 end:0x804A29B8 + .data start:0x8056EEB0 end:0x8056EF28 + .sdata2 start:0x8057F538 end:0x8057F580 egg/gfx/eggDrawPathDOF.cpp: .text start:0x804A29C0 end:0x804A4BE8 + .rodata start:0x804FBC70 end:0x804FBC88 .data start:0x8056EF28 end:0x8056EFA0 + .sdata2 start:0x8057F580 end:0x8057F5F8 egg/gfx/eggDrawPathLightMap.cpp: .text start:0x804A4BF0 end:0x804A54E8 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 81f62ff6..d14c421f 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -10654,7 +10654,7 @@ fn_8019C250 = .text:0x8019C250; // type:function size:0x4 fn_8019C260 = .text:0x8019C260; // type:function size:0x4 fn_8019C270 = .text:0x8019C270; // type:function size:0x4 fn_8019C280 = .text:0x8019C280; // type:function size:0x4 -fn_8019C290 = .text:0x8019C290; // type:function size:0x8 +getNumStep__Q23EGG13DrawPathBloomCFv = .text:0x8019C290; // type:function size:0x8 getNumStep__Q23EGG11DrawPathDOFCFv = .text:0x8019C2A0; // type:function size:0x8 build__27sFStateFct_c<11dStageMgr_c>FRC12sStateIDIf_c = .text:0x8019C2B0; // type:function size:0x60 dispose__27sFStateFct_c<11dStageMgr_c>FRP10sStateIf_c = .text:0x8019C310; // type:function size:0xC @@ -10676,7 +10676,7 @@ fn_8019C470 = .text:0x8019C470; // type:function size:0x10 SetBinary__Q23EGG19IBinaryFPCv = .text:0x8019C480; // type:function size:0x10 GetBinarySize__Q23EGG28IBinaryCFv = .text:0x8019C490; // type:function size:0x8 fn_8019C4A0 = .text:0x8019C4A0; // type:function size:0x10 -fn_8019C4B0 = .text:0x8019C4B0; // type:function size:0x8 +GetBinarySize__Q23EGG30IBinaryCFv = .text:0x8019C4B0; // type:function size:0x8 fn_8019C4C0 = .text:0x8019C4C0; // type:function size:0x10 finalizeState__26sFStateID_c<11dStageMgr_c>CFR11dStageMgr_c = .text:0x8019C4D0; // type:function size:0x30 executeState__26sFStateID_c<11dStageMgr_c>CFR11dStageMgr_c = .text:0x8019C500; // type:function size:0x30 @@ -10692,9 +10692,9 @@ fn_8019CEE0 = .text:0x8019CEE0; // type:function size:0x8 fn_8019CF20 = .text:0x8019CF20; // type:function size:0x8 fn_8019CF30 = .text:0x8019CF30; // type:function size:0x8 fn_8019CF40 = .text:0x8019CF40; // type:function size:0x8 -fn_8019CF50 = .text:0x8019CF50; // type:function size:0x8 -fn_8019CF60 = .text:0x8019CF60; // type:function size:0x8 -fn_8019CF70 = .text:0x8019CF70; // type:function size:0x8 +@24@SetBinaryInner__Q23EGG13DrawPathBloomFRCQ33EGG30IBinary3Bin = .text:0x8019CF50; // type:function size:0x8 +@24@SetBinaryInner__Q23EGG13DrawPathBloomFRCQ33EGG30IBinary3BinRCQ33EGG30IBinary3Binf = .text:0x8019CF60; // type:function size:0x8 +@24@GetBinaryInner__Q23EGG13DrawPathBloomCFPQ33EGG30IBinary3Bin = .text:0x8019CF70; // type:function size:0x8 fn_8019CF80 = .text:0x8019CF80; // type:function size:0x8 fn_8019CF90 = .text:0x8019CF90; // type:function size:0x8 fn_8019CFA0 = .text:0x8019CFA0; // type:function size:0x8 @@ -11262,8 +11262,8 @@ getNewStateID__86sStateMgr_c<17dLytCursorStick_c,20sStateMethodUsr_FI_c,12sFStat getStateID__86sStateMgr_c<17dLytCursorStick_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x801BD230; // type:function size:0x10 getOldStateID__86sStateMgr_c<17dLytCursorStick_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x801BD240; // type:function size:0x10 dCsGame_c_classInit__Fv = .text:0x801BD250; // type:function size:0x30 -fn_801BD280 = .text:0x801BD280; // type:function size:0x8C -fn_801BD310 = .text:0x801BD310; // type:function size:0x40 +__ct__17CsGameConfigMaybeFv = .text:0x801BD280; // type:function size:0x8C +__dt__17CsGameConfigMaybeFv = .text:0x801BD310; // type:function size:0x40 __ct__9dCsGame_cFv = .text:0x801BD350; // type:function size:0x4CC fn_801BD820 = .text:0x801BD820; // type:function size:0x40 fn_801BD860 = .text:0x801BD860; // type:function size:0x40 @@ -26430,7 +26430,7 @@ getVtxResult__Q23EGG9AnalizeDLCFv = .text:0x8049D770; // type:function size:0x8 __dt__Q23EGG9AnalizeDLFv = .text:0x8049D780; // type:function size:0x40 configure__Q23EGG10CapTextureFv = .text:0x8049D7C0; // type:function size:0x7C capture__Q23EGG10CapTextureFUsUsbi = .text:0x8049D840; // type:function size:0x184 -FUN_8049d9d0 = .text:0x8049D9D0; // type:function size:0x58 +fn_8049D9D0__Q23EGG10CapTextureFUc = .text:0x8049D9D0; // type:function size:0x58 calcColorGradient__Q23EGG27@unnamed@eggCpuTexture_cpp@FR8_GXColorRC8_GXColorRC8_GXColorf = .text:0x8049DA30; // type:function size:0x188 makeGradient__Q23EGG27@unnamed@eggCpuTexture_cpp@FiP8_GXColoriiiRC8_GXColorRC8_GXColor = .text:0x8049DBC0; // type:function size:0x450 __ct__Q23EGG10CpuTextureFv = .text:0x8049E010; // type:function size:0x44 @@ -26484,28 +26484,28 @@ ExecCallback_CALC_VIEW__Q23EGG12DrawPathBaseFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g scnProcDraw__Q23EGG12DrawPathBaseFUs = .text:0x804A0E60; // type:function size:0x20 @8@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E80; // type:function size:0x8 scope:weak @20@__dt__Q23EGG12DrawPathBaseFv = .text:0x804A0E90; // type:function size:0x8 scope:weak -FUN_804a0ea0 = .text:0x804A0EA0; // type:function size:0x188 +__ct__Q23EGG13DrawPathBloomFv = .text:0x804A0EA0; // type:function size:0x188 __dt__Q23EGG14PostEffectMaskFv = .text:0x804A1030; // type:function size:0x40 __dt__Q23EGG20PostEffectBlurGatherFv = .text:0x804A1070; // type:function size:0x40 __dt__Q23EGG16PostEffectSimpleFv = .text:0x804A10B0; // type:function size:0x40 -FUN_804a10f0 = .text:0x804A10F0; // type:function size:0x60 -FUN_804a1150 = .text:0x804A1150; // type:function size:0x21C -FUN_804a1370 = .text:0x804A1370; // type:function size:0x7A4 -FUN_804a1b20 = .text:0x804A1B20; // type:function size:0x53C -FUN_804a2060 = .text:0x804A2060; // type:function size:0x1D4 -FUN_804a2240 = .text:0x804A2240; // type:function size:0x714 +__dt__Q23EGG13DrawPathBloomFv = .text:0x804A10F0; // type:function size:0x60 +internalResetForDraw__Q23EGG13DrawPathBloomFv = .text:0x804A1150; // type:function size:0x21C +internalDraw__Q23EGG13DrawPathBloomFUs = .text:0x804A1370; // type:function size:0x7A4 +SetBinaryInner__Q23EGG13DrawPathBloomFRCQ33EGG30IBinary3Bin = .text:0x804A1B20; // type:function size:0x53C +GetBinaryInner__Q23EGG13DrawPathBloomCFPQ33EGG30IBinary3Bin = .text:0x804A2060; // type:function size:0x1D4 +SetBinaryInner__Q23EGG13DrawPathBloomFRCQ33EGG30IBinary3BinRCQ33EGG30IBinary3Binf = .text:0x804A2240; // type:function size:0x714 FUN_804a2960 = .text:0x804A2960; // type:function size:0x28 -fn_804A2990 = .text:0x804A2990; // type:function size:0x8 -fn_804A29A0 = .text:0x804A29A0; // type:function size:0x8 -fn_804A29B0 = .text:0x804A29B0; // type:function size:0x8 +@8@__dt__Q23EGG13DrawPathBloomFv = .text:0x804A2990; // type:function size:0x8 +@20@__dt__Q23EGG13DrawPathBloomFv = .text:0x804A29A0; // type:function size:0x8 +@24@__dt__Q23EGG13DrawPathBloomFv = .text:0x804A29B0; // type:function size:0x8 __ct__Q23EGG11DrawPathDOFFv = .text:0x804A29C0; // type:function size:0x164 __dt__Q23EGG11DrawPathDOFFv = .text:0x804A2B30; // type:function size:0x104 -fn_804A2C40 = .text:0x804A2C40; // type:function size:0x40 -fn_804A2C80 = .text:0x804A2C80; // type:function size:0x9C +__dt__Q23EGG17PostEffectMaskDOFFv = .text:0x804A2C40; // type:function size:0x40 +execute__Q23EGG11DrawPathDOFFv = .text:0x804A2C80; // type:function size:0x9C internalResetForDraw__Q23EGG11DrawPathDOFFv = .text:0x804A2D20; // type:function size:0x324 -internalDraw__Q23EGG11DrawPathDOFFv = .text:0x804A3050; // type:function size:0xCC -FUN_804a3120 = .text:0x804A3120; // type:function size:0x9A4 -EGG__DrawPathDOF__internalDraw = .text:0x804A3AD0; // type:function size:0x648 +internalDraw__Q23EGG11DrawPathDOFFUs = .text:0x804A3050; // type:function size:0xCC +internalDrawVariant01__Q23EGG11DrawPathDOFFUs = .text:0x804A3120; // type:function size:0x9A4 +internalDrawVariant2__Q23EGG11DrawPathDOFFUs = .text:0x804A3AD0; // type:function size:0x648 FUN_804a4120 = .text:0x804A4120; // type:function size:0x224 FUN_804a4350 = .text:0x804A4350; // type:function size:0xDC SetBinaryInner__Q23EGG11DrawPathDOFFRCQ33EGG28IBinary3Bin = .text:0x804A4430; // type:function size:0x238 @@ -37361,7 +37361,7 @@ 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 __vt__Q23EGG12DrawPathBase = .data:0x8056EE60; // type:object size:0x50 -lbl_8056EEB0 = .data:0x8056EEB0; // type:object size:0x78 +__vt__Q23EGG13DrawPathBloom = .data:0x8056EEB0; // type:object size:0x78 __vt__Q23EGG11DrawPathDOF = .data:0x8056EF28; // type:object size:0x78 __vt__Q23EGG16DrawPathLightMap = .data:0x8056EFA0; // type:object size:0x50 __vt__Q23EGG3Fog = .data:0x8056EFF0; // type:object size:0x20 diff --git a/include/egg/egg_types.h b/include/egg/egg_types.h index d72a6037..1b218479 100644 --- a/include/egg/egg_types.h +++ b/include/egg/egg_types.h @@ -36,6 +36,8 @@ class PostEffectBase; class PostEffectBlur; class PostEffectBlurGather; class PostEffectHDR; +class PostEffectMask; +class PostEffectMaskDOF; class PostEffectSimple; class PostEffectUnk2; class ResTIMG; diff --git a/include/egg/gfx/eggCapTexture.h b/include/egg/gfx/eggCapTexture.h index 955504eb..a3887e5b 100644 --- a/include/egg/gfx/eggCapTexture.h +++ b/include/egg/gfx/eggCapTexture.h @@ -18,6 +18,7 @@ public: virtual void configure() override; // at 0xC void capture(u16 x, u16 y, bool upscale, int format); + void fn_8049D9D0(u8 arg); void setPixModeSync(bool enable) { if (enable) { diff --git a/include/egg/gfx/eggDrawPathBloom.h b/include/egg/gfx/eggDrawPathBloom.h index 7f0b0f30..eca7b2b7 100644 --- a/include/egg/gfx/eggDrawPathBloom.h +++ b/include/egg/gfx/eggDrawPathBloom.h @@ -2,17 +2,72 @@ #define EGG_DRAW_PATH_BLOOM_H #include "egg/gfx/eggDrawPathBase.h" +#include "egg/gfx/eggPostEffectBlur.h" +#include "egg/gfx/eggPostEffectBlurGather.h" +#include "egg/gfx/eggPostEffectMask.h" +#include "egg/gfx/eggPostEffectSimple.h" +#include "egg/prim/eggBinary.h" +#include "rvl/GX/GXTypes.h" + namespace EGG { -class DrawPathBloom : public DrawPathBase { +class DrawPathBloom : public DrawPathBase, public IBinary { + struct BinData {}; + + // Size 0x20? + struct SubData { + /* 0x00 */ f32 field_0x00; + /* 0x04 */ f32 field_0x04; + /* 0x08 */ u8 field_0x08; + /* 0x09 */ u8 _0x09[0x20 - 0x09]; + }; + + // Not sure about this union thing but need to prevent compiler + // from trying fancy struct copying + struct Data { + union { + struct { + /* 0x00 */ f32 field_0x00; + /* 0x04 */ GXColor field_0x04; + /* 0x08 */ GXColor field_0x08; + /* 0x0C */ u16 field_0x0C; + /* 0x10 */ SubData field_0x10[3]; + /* 0x50 */ u8 field_0x50; + /* 0x51 */ u8 field_0x51; + /* 0x52 */ u8 field_0x52; + /* 0x53 */ u8 _0x53[0x6C - 0x53]; + /* 0x6C */ f32 field_0x6C; + /* 0x70 */ f32 field_0x70; + + }; + }; + }; + public: + DrawPathBloom(); virtual ~DrawPathBloom(); virtual u16 getNumStep() const override { return 3; } + virtual void internalResetForDraw() override; + virtual void internalDraw(u16) override; + + virtual void SetBinaryInner(const Bin &) override; + virtual void GetBinaryInner(Bin *) const override; + virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + private: + /* 0x01C */ u8 field_0x01C; + /* 0x01D */ u8 field_0x01D; + /* 0x020 */ PostEffectMask mMask; + /* 0x1E0 */ PostEffectBlur mBlur1; + /* 0x258 */ PostEffectBlur mBlur2; + /* 0x2D0 */ PostEffectBlurGather mBlurGather; + /* 0x340 */ PostEffectSimple mSimple; + /* 0x37C */ u32 field_0x37C; + /* 0x380 */ Data field_0x380; }; } // namespace EGG diff --git a/include/egg/gfx/eggDrawPathDOF.h b/include/egg/gfx/eggDrawPathDOF.h index ae1cce6c..055e603a 100644 --- a/include/egg/gfx/eggDrawPathDOF.h +++ b/include/egg/gfx/eggDrawPathDOF.h @@ -2,7 +2,9 @@ #define EGG_DRAW_PATH_DOF_H #include "egg/gfx/eggDrawPathBase.h" +#include "egg/gfx/eggTextureBuffer.h" #include "egg/prim/eggBinary.h" +#include "egg/egg_types.h" namespace EGG { @@ -24,8 +26,42 @@ public: virtual void GetBinaryInner(Bin *) const override; virtual void SetBinaryInner(const Bin &, const Bin &, f32) override; + + void execute(); + private: - void *IHaveMembers; + void internalDrawVariant01(u16); + void internalDrawVariant2(u16); + + void afterDraw(u16 x, u16 y, u16 width, u16 height); + + /* 0x1C */ u16 field_0x1C; + /* 0x1E */ u8 field_0x1E; + /* 0x1F */ u8 field_0x1F; + /* 0x20 */ s32 field_0x20; + /* 0x24 */ f32 field_0x24; + /* 0x28 */ f32 field_0x28; + /* 0x2C */ f32 field_0x2C; + /* 0x30 */ f32 field_0x30; + /* 0x34 */ s32 field_0x34; + /* 0x38 */ s32 field_0x38; + + /* 0x3C */ u8 _0x3C[0x5C - 0x3C]; + + /* 0x5C */ f32 field_0x5C; + /* 0x60 */ f32 field_0x60; + /* 0x64 */ f32 field_0x64; + /* 0x68 */ f32 field_0x68; + /* 0x6C */ f32 field_0x6C; + /* 0x70 */ f32 field_0x70; + /* 0x74 */ f32 field_0x74; + /* 0x78 */ f32 field_0x78; + /* 0x7C */ f32 field_0x7C; + /* 0x80 */ u8 field_0x80; + /* 0x84 */ PostEffectBlur *mpBlur; + /* 0x88 */ PostEffectMaskDOF *mpMaskDof; + /* 0x8C */ TextureBuffer *mpTextureBuffer; + /* 0x90 */ PostEffectMask *mpMask; }; } // namespace EGG diff --git a/include/egg/gfx/eggFrustum.h b/include/egg/gfx/eggFrustum.h index 5165935c..ded3ea33 100644 --- a/include/egg/gfx/eggFrustum.h +++ b/include/egg/gfx/eggFrustum.h @@ -24,8 +24,8 @@ public: CANVASMODE_0, CANVASMODE_1, }; - - protected: + +protected: ProjectionType mProjType; // at 0x0 CanvasMode mCanvasMode; // at 0x4 nw4r::math::VEC2 mSize; // at 0x8 @@ -140,6 +140,28 @@ public: mFlags |= flag; } + f32 TranslateDepthToViewSpace(f32 depth) const { + depth = -depth; + f32 bound = -1e-6f; + f32 val = depth >= bound ? bound : depth; + ProjectionType proj = GetProjectionType(); + f32 near = mNearZ; + f32 far = mFarZ; + f32 diff = far - near; + f32 viewDepth; + if (proj == PROJ_PERSP) { + viewDepth = ((val * -near) / diff - (far * near) / diff) / -val + 1.0f; + } else { + viewDepth = (-val - near) / diff; + } + if (viewDepth < 0.0f) { + return 0.0f; + } else if (viewDepth > 1.0f) { + return 1.0f; + } + return viewDepth; + } + private: void SetProjectionPerspectiveGX_() const; void SetProjectionOrthographicGX_() const; diff --git a/include/egg/gfx/eggPostEffectBase.h b/include/egg/gfx/eggPostEffectBase.h index 16f85642..5b2219cd 100644 --- a/include/egg/gfx/eggPostEffectBase.h +++ b/include/egg/gfx/eggPostEffectBase.h @@ -27,6 +27,18 @@ public: return mRotation; } + void setRot(f32 rot) { + mRotation = rot; + } + + void setCapTexture(CapTexture *tex) { + mTex1.mpTex = tex; + } + + void setCapTexMapId(GXTexMapID id) { + mTex1.mTexMapID = id; + } + public: u32 field_0x00; // at 0x0 CapTextureWrapper mTex1; // at 0x4 @@ -51,8 +63,9 @@ public: static void lerpColor(GXColor &, const GXColor &, const GXColor &, f32); void getBaseTexMtx(nw4r::math::MTX34 *mtx) const; -protected: +public: virtual void draw(f32 width, f32 height); // at 0xC +protected: virtual void setMaterialInternal() {} // at 0x10 virtual void loadTextureInternal(); // at 0x14 virtual void drawScreenInternal(f32 offsetX, f32 offsetY, f32 width, f32 height); // at 0x18 diff --git a/include/egg/gfx/eggPostEffectBlur.h b/include/egg/gfx/eggPostEffectBlur.h index 35db7a39..de6d9754 100644 --- a/include/egg/gfx/eggPostEffectBlur.h +++ b/include/egg/gfx/eggPostEffectBlur.h @@ -33,6 +33,10 @@ public: field_0x30 = val; } + void setField0x2C(int i) { + field_0x2C = i; + } + void setStage0Field0(u8 u1) { field_0x38[0].field_0x00 = u1; } @@ -45,6 +49,13 @@ public: field_0x38[0].field_0x0C = f; } + void setStage0ColorThing(u8 i) { + f32 color = (255.0f / field_0x38[0].field_0x00) + 0.5f; + f32 f = (i * 1.75f) / field_0x38[0].field_0x00; + f32 alpha = f <= 255.0f ? f : 255.0f; + field_0x38[0].field_0x01 = (GXColor){color, color, color, alpha}; + } + private: void drawInternal(u8, u8, f32, f32); diff --git a/include/egg/gfx/eggPostEffectMask.h b/include/egg/gfx/eggPostEffectMask.h index 97cfbf61..113ec6cf 100644 --- a/include/egg/gfx/eggPostEffectMask.h +++ b/include/egg/gfx/eggPostEffectMask.h @@ -16,6 +16,14 @@ public: return static_cast(field_0x1BC); } + void setField_0x2C(int i) { + field_0x2C = i; + } + + void setField_0x34(f32 f) { + field_0x34 = f; + } + private: /* 0x2C */ int field_0x2C; /* 0x30 */ GXColor mColor; diff --git a/include/egg/gfx/eggPostEffectMaskDOF.h b/include/egg/gfx/eggPostEffectMaskDOF.h index 56ca76d1..297843ec 100644 --- a/include/egg/gfx/eggPostEffectMaskDOF.h +++ b/include/egg/gfx/eggPostEffectMaskDOF.h @@ -20,6 +20,22 @@ public: static const GXColor &getFarColor(); static const GXColor &getCenterColor(); + void setParam0x44(f32 f) { + field_0x44 = f; + } + + void setParam0x48(f32 f) { + field_0x48 = f; + } + + void setParam0x4C(f32 f) { + field_0x4C = f; + } + + void setCpuTexArrIdx(int i){ + mCpuTexArrIdx = i; + } + private: /* 0x2C */ u8 field_0x2C; /* 0x30 */ CpuTexture *mpCpuTexArr[3]; diff --git a/include/egg/gfx/eggPostEffectSimple.h b/include/egg/gfx/eggPostEffectSimple.h index 4de2455f..9f26b738 100644 --- a/include/egg/gfx/eggPostEffectSimple.h +++ b/include/egg/gfx/eggPostEffectSimple.h @@ -10,6 +10,10 @@ public: PostEffectSimple(); virtual void setMaterialInternal() override; + void setField0x38(s32 v) { + field_0x38 = v; + } + private: /* 0x2C */ GXColor field_0x2C; /* 0x30 */ f32 field_0x30; diff --git a/include/egg/gfx/eggScreen.h b/include/egg/gfx/eggScreen.h index f2638357..44fd56da 100644 --- a/include/egg/gfx/eggScreen.h +++ b/include/egg/gfx/eggScreen.h @@ -111,10 +111,18 @@ public: return val * StateGX::s_widthEfb / GetSizeXMax(GetComputedTVMode()); } + f32 UnscaleByX(f32 val) const { + return val * GetSizeXMax(GetComputedTVMode()) / StateGX::s_widthEfb; + } + f32 ScaleByY(f32 val) const { return val * StateGX::s_heightEfb / GetSizeYMax(GetComputedTVMode()); } + f32 UnscaleByY(f32 val) const { + return val * GetSizeYMax(GetComputedTVMode()) / StateGX::s_heightEfb; + } + private: const Screen *mParent; // at 0x3C nw4r::math::VEC2 mPosition; // at 0x40 diff --git a/include/egg/gfx/eggStateEfb.h b/include/egg/gfx/eggStateEfb.h index eabf22d2..93386936 100644 --- a/include/egg/gfx/eggStateEfb.h +++ b/include/egg/gfx/eggStateEfb.h @@ -7,6 +7,7 @@ namespace EGG { class StateEfb { +public: enum BufferType { BUFFER_0, BUFFER_1, @@ -21,7 +22,7 @@ class StateEfb { u32 userData; u32 field_0x08; }; - +private: static Buffer spBufferSet[BUFFER_MAX]; static f32 sWorkSpaceV[6]; static f32 sWorkSpaceHideV[6]; @@ -30,18 +31,22 @@ class StateEfb { static s32 sPushCount; static u32 sFlag; - static f32 *fn_804B4550(); static bool GetShouldCapture(); static bool GetUseTfRgb565(); - -public: + + public: + static bool CheckFlag0x2() { + return (sFlag & 2) != 0; + } + static void Clean(); static TextureBuffer *captureEfb(BufferType type, bool, u32 userData); static bool releaseEfb(BufferType type, u32 userData); - + // Unknown names static void fn_804B4270(BufferType type, u32 userData); static void fn_804B4310(BufferType type, u32 userData); + static f32 *fn_804B4550(); }; } // namespace EGG diff --git a/src/egg/gfx/eggCapTexture.cpp b/src/egg/gfx/eggCapTexture.cpp index 1fc25133..0847d808 100644 --- a/src/egg/gfx/eggCapTexture.cpp +++ b/src/egg/gfx/eggCapTexture.cpp @@ -52,4 +52,18 @@ void CapTexture::capture(u16 x, u16 y, bool upscale, int format) { } } +void CapTexture::fn_8049D9D0(u8 arg) { + onCapFlag(0x8); + + CopyFilter v; + v.values[0] = arg; + v.values[1] = 0; + v.values[2] = 1; + v.values[3] = 64 - (2 * arg) - 1; + v.values[4] = 0; + v.values[5] = arg; + v.values[6] = 0; + setCopyFilter(v); +} + } // namespace EGG diff --git a/src/egg/gfx/eggDrawPathBloom.cpp b/src/egg/gfx/eggDrawPathBloom.cpp index 5a42210b..a583aa24 100644 --- a/src/egg/gfx/eggDrawPathBloom.cpp +++ b/src/egg/gfx/eggDrawPathBloom.cpp @@ -1,3 +1,49 @@ #include "egg/gfx/eggDrawPathBloom.h" +#include "egg/gfx/eggDrawGX.h" -namespace EGG {} // namespace EGG +namespace EGG { + +DrawPathBloom::DrawPathBloom(): field_0x01C(1), field_0x01D(8), field_0x37C(0) { + Data nullDat = {0}; + field_0x380 = nullDat; + + mSimple.setField0x38(0); + field_0x380.field_0x00 = 0.5f; + field_0x380.field_0x04 = DrawGX::WHITE; + field_0x380.field_0x08 = DrawGX::WHITE; + field_0x380.field_0x0C = 0x21; + + field_0x380.field_0x10[0].field_0x00 = 1.0f; + field_0x380.field_0x10[0].field_0x04 = 0.3f; + field_0x380.field_0x10[0].field_0x08 = 0x15; + + field_0x380.field_0x10[1].field_0x00 = 2.0f; + field_0x380.field_0x10[1].field_0x04 = 0.08f; + field_0x380.field_0x10[1].field_0x08 = 0x15; + + field_0x380.field_0x10[2].field_0x00 = 4.0f; + field_0x380.field_0x10[2].field_0x04 = 0.04f; + field_0x380.field_0x10[2].field_0x08 = 0x15; + + field_0x380.field_0x51 = 2; + field_0x380.field_0x50 = 1; + + field_0x380.field_0x70 = 0.0f; + field_0x380.field_0x6C = 0.0f; + + field_0x380.field_0x52 = 0x15; +} + +DrawPathBloom::~DrawPathBloom() {} + +void DrawPathBloom::internalResetForDraw() {} + +void DrawPathBloom::internalDraw(u16 idx) {} + +void DrawPathBloom::SetBinaryInner(const Bin &bin) {} + +void DrawPathBloom::GetBinaryInner(Bin *pBin) const {} + +void DrawPathBloom::SetBinaryInner(const Bin &, const Bin &, f32) {} + +} // namespace EGG diff --git a/src/egg/gfx/eggDrawPathDOF.cpp b/src/egg/gfx/eggDrawPathDOF.cpp index 11413838..012259fa 100644 --- a/src/egg/gfx/eggDrawPathDOF.cpp +++ b/src/egg/gfx/eggDrawPathDOF.cpp @@ -1,14 +1,220 @@ #include "egg/gfx/eggDrawPathDOF.h" +#include "common.h" +#include "egg/gfx/eggDrawGX.h" +#include "egg/gfx/eggGlobalDrawState.h" +#include "egg/gfx/eggPostEffectBase.h" +#include "egg/gfx/eggPostEffectBlur.h" +#include "egg/gfx/eggPostEffectMask.h" +#include "egg/gfx/eggPostEffectMaskDOF.h" +#include "egg/gfx/eggPostEffectSimple.h" +#include "egg/gfx/eggScreen.h" +#include "egg/gfx/eggStateEfb.h" +#include "egg/gfx/eggStateGX.h" +#include "egg/gfx/eggTextureBuffer.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTypes.h" + namespace EGG { -DrawPathDOF::DrawPathDOF() {} +DrawPathDOF::DrawPathDOF() + : field_0x1C(1), + field_0x20(1), + field_0x24(30.0f), + field_0x28(20.0f), + field_0x2C(20.0f), + field_0x30(1.6f), + field_0x34(0), + field_0x38(2), + field_0x5C(0.0f), + field_0x60(0.0f), + field_0x64(0.4f), + field_0x68(0.2f), + field_0x6C(-0.0075f), + field_0x70(-0.0075f), + field_0x74(10.0f), + field_0x78(15.0f), + field_0x7C(1.0f), + field_0x80(21), + mpBlur(nullptr), + mpMask(nullptr), + mpTextureBuffer(nullptr), + mpMaskDof(nullptr) { + mpMaskDof = new PostEffectMaskDOF(); + mpBlur = new PostEffectBlur(); + mpBlur->setField0x2C(1); + mpMask = new PostEffectMask(); -DrawPathDOF::~DrawPathDOF() {} + mpMask->setField_0x00(0); + mpMask->setField_0x34(0.0f); + mpMask->setField_0x2C(0); + field_0x1E = 0xFF; + field_0x1F = 0xFF; +} -void DrawPathDOF::internalDraw(u16) {} +DrawPathDOF::~DrawPathDOF() { + delete mpMaskDof; + mpMaskDof = nullptr; + delete mpBlur; + mpBlur = nullptr; + delete mpMask; + mpMask = nullptr; +} -void DrawPathDOF::internalResetForDraw() {} +void DrawPathDOF::execute() { + field_0x5C += field_0x6C * field_0x7C; + field_0x60 += field_0x70 * field_0x7C; + + if (field_0x5C < -1.0f) { + field_0x5C += 2.0f; + } else if (field_0x5C > 1.0f) { + // @bug typo? + field_0x5C -= -2.0f; + } + + if (field_0x60 < -1.0f) { + field_0x60 += 2.0f; + } else if (field_0x60 > 1.0f) { + field_0x60 -= 2.0f; + } +} + +static int sMaskDofArray[] = {0, 1, 2}; +static u8 sBlurArray[] = {4, 2, 1, 0}; + +void DrawPathDOF::internalResetForDraw() { + // Tons of regswaps... + f32 a = GlobalDrawState::getScreen().TranslateDepthToViewSpace(field_0x24); + f32 b = GlobalDrawState::getScreen().TranslateDepthToViewSpace(field_0x24 - field_0x28 / 2.0f); + f32 c = GlobalDrawState::getScreen().TranslateDepthToViewSpace(field_0x24 + field_0x28 / 2.0f); + + // TODO + if (c < b + 1e-6f) { + c = b + 1e-6f; + + if (b < 1.0f) { + c = 1.0f; + b -= 1e-6f; + } + } + mpMaskDof->setParam0x48(b); + mpMaskDof->setParam0x44(a); + mpMaskDof->setParam0x4C(c); + + if (field_0x38 >= 3) { + field_0x38 = 2; + } + + mpMaskDof->setCpuTexArrIdx(sMaskDofArray[field_0x38]); + mpBlur->setStage0Field0(sBlurArray[field_0x34]); + mpBlur->setStage0F(field_0x34 != 2 ? field_0x30 : 0.0f); + // HELP + mpBlur->setStage0ColorThing(field_0x1E); +} + +void DrawPathDOF::internalDraw(u16 idx) { + if (idx == 0) { + if (StateEfb::CheckFlag0x2() == 0) { + StateEfb::fn_804B4270( + static_cast((field_0x1C >> 2) & 1), reinterpret_cast(this) + ); + } + StateGX::invalidateTexAllGX(); + } + + if (field_0x20 == 2) { + internalDrawVariant2(idx); + } else { + internalDrawVariant01(idx); + } + + switch (idx) { + case 1: + StateEfb::fn_804B4310(StateEfb::BUFFER_0, reinterpret_cast(this)); + StateEfb::releaseEfb(StateEfb::BUFFER_3, reinterpret_cast(this)); + break; + case 2: + if (mpTextureBuffer != nullptr) { + mpTextureBuffer->free(); + mpTextureBuffer = nullptr; + } + } +} + +void DrawPathDOF::internalDrawVariant01(u16 idx) {} + +void DrawPathDOF::internalDrawVariant2(u16 idx) { + const Screen &screen = GlobalDrawState::getScreen(); + const Screen::DataEfb &efb = screen.GetDataEfb(); + switch (idx) { + case 0: { + TextureBuffer *capturedBuf = StateEfb::captureEfb(StateEfb::BUFFER_3, false, reinterpret_cast(this)); + StateGX::GXSetPixelFmt_(GX_PF_RGB8_Z24, GX_ZC_LINEAR); + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(false); + StateGX::ScopedDither ditherGuard(false); + PostEffectBase::setProjection(screen); + f32 *floats = StateEfb::fn_804B4550(); + f32 scale = (field_0x1C & 4) != 0 ? 0.25f : 0.5f; + f32 width1 = screen.GetWidth() * scale; + f32 height1 = screen.GetHeight() * scale; + + f32 rot = 0.5f; + + u16 width = efb.vp.x2 * scale; + u16 height = efb.vp.y2 * scale; + + PostEffectSimple effect; + effect.setCapTexMapId(GX_TEXMAP0); + effect.setField0x38(0); + effect.setField_0x00(0); + effect.setRot(rot); + + effect.setCapTexture(capturedBuf); + // TODO tons of problems in these UnscaleByX inlines that probably exist + effect.draw(screen.UnscaleByX(height), screen.UnscaleByY(width)); + TextureBuffer *pTex2 = TextureBuffer::alloc(height, width, GX_TF_RGBA8); + pTex2->fn_8049D9D0(field_0x80); + pTex2->capture(floats[0], floats[1], false, -1); + mpBlur->setCapTexture(pTex2); + mpBlur->setCapTexMapId(GX_TEXMAP0); + mpBlur->setRot(-rot); + mpBlur->draw(width1, height1); + + if (pTex2 != nullptr) { + pTex2->free(); + } + afterDraw(floats[0], floats[1], width, height); + StateGX::GXSetPixelFmt_(StateGX::s_pixFormat, StateGX::s_zFmt16); + break; + } + case 2: { + StateGX::ScopedColor colorGuard(true); + StateGX::ScopedAlpha alphaGuard(false); + StateGX::ScopedDither ditherGuard(true); + + Screen screenCpy(screen); + screenCpy.SetOffset(nw4r::math::VEC2(0.0f, 0.0f)); + screenCpy.SetScale(nw4r::math::VEC3(1.0f, 1.0f, 1.0f)); + screenCpy.SetFlag(Screen::FLAG_0x40); + screenCpy.SetProjectionGX(); + DrawGX::SetMat_ColorChannel(DrawGX::COLORCHAN_1); + DrawGX::SetMat_TexGen(DrawGX::TEXGEN_1); + DrawGX::SetMat_Ind(); + DrawGX::SetMat_Tev(GX_TEVSTAGE0, DrawGX::TEV_2); + GXSetTevAlphaIn(GX_TEVSTAGE0,GX_CA_ZERO,GX_CA_ZERO,GX_CA_ZERO,GX_CA_RASA); + DrawGX::SetMat_PE(DrawGX::ZMODE_2, DrawGX::BLEND_0); + DrawGX::SetVtxState(DrawGX::VTX_TYPE_7); + mpTextureBuffer->load(GX_TEXMAP0); + + for (int i = 0; i < 2; i++) { + // TODO + } + + break; + } + } +} void DrawPathDOF::SetBinaryInner(const Bin &bin) {} From 2873a1f1b20b650b02a2a4674cf09915e122a517 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 29 Mar 2025 21:22:15 +0100 Subject: [PATCH 56/62] Add placeholders --- src/egg/gfx/eggDrawPathBloom.cpp | 20 +++++++++++++++----- src/egg/gfx/eggDrawPathDOF.cpp | 12 +++++++++--- src/egg/gfx/eggFog.cpp | 4 +++- src/egg/gfx/eggLightManager.cpp | 8 ++++++++ src/egg/gfx/eggLightTexture.cpp | 4 +--- src/egg/gfx/eggScreenEffectBlur.cpp | 4 +++- 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/egg/gfx/eggDrawPathBloom.cpp b/src/egg/gfx/eggDrawPathBloom.cpp index a583aa24..844af420 100644 --- a/src/egg/gfx/eggDrawPathBloom.cpp +++ b/src/egg/gfx/eggDrawPathBloom.cpp @@ -36,14 +36,24 @@ DrawPathBloom::DrawPathBloom(): field_0x01C(1), field_0x01D(8), field_0x37C(0) { DrawPathBloom::~DrawPathBloom() {} -void DrawPathBloom::internalResetForDraw() {} +void DrawPathBloom::internalResetForDraw() { + // TODO +} -void DrawPathBloom::internalDraw(u16 idx) {} +void DrawPathBloom::internalDraw(u16 idx) { + // TODO +} -void DrawPathBloom::SetBinaryInner(const Bin &bin) {} +void DrawPathBloom::SetBinaryInner(const Bin &bin) { + // TODO +} -void DrawPathBloom::GetBinaryInner(Bin *pBin) const {} +void DrawPathBloom::GetBinaryInner(Bin *pBin) const { + // TODO +} -void DrawPathBloom::SetBinaryInner(const Bin &, const Bin &, f32) {} +void DrawPathBloom::SetBinaryInner(const Bin &, const Bin &, f32) { + // TODO +} } // namespace EGG diff --git a/src/egg/gfx/eggDrawPathDOF.cpp b/src/egg/gfx/eggDrawPathDOF.cpp index 012259fa..b51b64cd 100644 --- a/src/egg/gfx/eggDrawPathDOF.cpp +++ b/src/egg/gfx/eggDrawPathDOF.cpp @@ -216,10 +216,16 @@ void DrawPathDOF::internalDrawVariant2(u16 idx) { } } -void DrawPathDOF::SetBinaryInner(const Bin &bin) {} +void DrawPathDOF::SetBinaryInner(const Bin &bin) { + // TODO +} -void DrawPathDOF::GetBinaryInner(Bin *pBin) const {} +void DrawPathDOF::GetBinaryInner(Bin *pBin) const { + // TODO +} -void DrawPathDOF::SetBinaryInner(const Bin &, const Bin &, f32) {} +void DrawPathDOF::SetBinaryInner(const Bin &, const Bin &, f32) { + // TODO +} } // namespace EGG diff --git a/src/egg/gfx/eggFog.cpp b/src/egg/gfx/eggFog.cpp index 06adfc12..cc66c567 100644 --- a/src/egg/gfx/eggFog.cpp +++ b/src/egg/gfx/eggFog.cpp @@ -61,7 +61,9 @@ void Fog::GetBinaryInner(Bin *pBin) const { pBin->mData.mFlag2 = mFlags; } -void Fog::SetBinaryInner(const Bin &, const Bin &, f32) {} +void Fog::SetBinaryInner(const Bin &, const Bin &, f32) { + // TODO +} Fog::~Fog() {} diff --git a/src/egg/gfx/eggLightManager.cpp b/src/egg/gfx/eggLightManager.cpp index 3e63eb82..003b8703 100644 --- a/src/egg/gfx/eggLightManager.cpp +++ b/src/egg/gfx/eggLightManager.cpp @@ -270,6 +270,10 @@ void LightManager::AnmScnRes_GetAmbLightColor( obj->mLightObj.a = (color >> 0) & 0xFF; } +void LightManager::SetBinaryInner(const Bin &) { + // TODO +} + void LightManager::GetBinaryInner(Bin *bin) const { // NONMATCHING - regswaps, loop increments u16 numObjs = mSavedCounts.mNumEggLightObjects; @@ -298,6 +302,10 @@ void LightManager::GetBinaryInner(Bin *bin) const { bin->mData.mColor = mColor; } +void LightManager::SetBinaryInner(const Bin &, const Bin &, f32) { + // TODO +} + void LightManager::BecomeInvalidLight(int idx) { mpLightData[idx].mLightObject.ClearOtherFlag1(); } diff --git a/src/egg/gfx/eggLightTexture.cpp b/src/egg/gfx/eggLightTexture.cpp index d6d4f32d..428dbea9 100644 --- a/src/egg/gfx/eggLightTexture.cpp +++ b/src/egg/gfx/eggLightTexture.cpp @@ -593,9 +593,7 @@ void LightTexture::addLight(const EGG::LightObject &obj) { } void LightTexture::SetBinaryInner(const Bin &bin) { - // Not bothering with version differences right now, - // since the game uses V3 and GetBinaryInner is enough - // for the structure + // TODO } void LightTexture::GetBinaryInner(Bin *pOutBin) const { diff --git a/src/egg/gfx/eggScreenEffectBlur.cpp b/src/egg/gfx/eggScreenEffectBlur.cpp index 25b379a7..afe15f76 100644 --- a/src/egg/gfx/eggScreenEffectBlur.cpp +++ b/src/egg/gfx/eggScreenEffectBlur.cpp @@ -167,6 +167,8 @@ void ScreenEffectBlur::GetBinaryInner(Bin *bin) const { bin->mData.field_0x1F = field_0x28.a; } -void ScreenEffectBlur::SetBinaryInner(const Bin &bin1, const Bin &bin2, f32 blend) {} +void ScreenEffectBlur::SetBinaryInner(const Bin &bin1, const Bin &bin2, f32 blend) { + // TODO +} } // namespace EGG From 70de7755093615fe483e3e7e09f39659a4123abb Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sat, 29 Mar 2025 23:41:41 -0400 Subject: [PATCH 57/62] cpu Texture better --- src/egg/gfx/eggCpuTexture.cpp | 67 +++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/src/egg/gfx/eggCpuTexture.cpp b/src/egg/gfx/eggCpuTexture.cpp index 955641a4..9cf4860c 100644 --- a/src/egg/gfx/eggCpuTexture.cpp +++ b/src/egg/gfx/eggCpuTexture.cpp @@ -173,8 +173,6 @@ void CpuTexture::buildHeader() const { extern "C" double sqrt(double); void CpuTexture::fillNormalMapSphere(f32 f1, f32 f2) { - // NONMATCHING - // fpr regswaps f32 mid = static_cast(mWidth / 2); for (u16 y = 0; y < mHeight; y++) { @@ -184,11 +182,13 @@ void CpuTexture::fillNormalMapSphere(f32 f1, f32 f2) { f32 fx = f1 * ((x + f2) - mid); f32 fy = f1 * -((y + f2) - mid); - f32 fz = mid * mid - (fx * fx + fy * fy); - vec.x = fx; - vec.y = fy; - vec.z = fz < 0.0f ? 0.0f : (f32)sqrt(fz); + f32 mid2 = mid * mid; + f32 fz = mid2 - (fx * fx + fy * fy); + + vec(0) = fx; + vec(1) = fy; + vec(2) = fz < Math::zero() ? Math::zero() : (f32)sqrt(fz); PSVECNormalize(vec, vec); GXUtility::getNormalColor(c, vec); @@ -202,33 +202,33 @@ void CpuTexture::fillNormalMapSphere(f32 f1, f32 f2) { void CpuTexture::fillGradient( int op, int unk, u16 start, u16 end, const GXColor &c1, const GXColor &c2, bool b1, bool b2 ) { + // NONMATCHING - regswaps + GXColor gradient[1024]; GXColor colors[256]; - // NONMATCHING - regswaps bool swapMode = unk == 0x73 || unk == 0x53; - u16 width = swapMode ? mWidth : mHeight; - int size = width; u16 height = swapMode ? mHeight : mWidth; - int mid = width / 2; - makeGradient(op, gradient, size, start, end, c1, c2); + u16 mid = width / 2; + + makeGradient(op, gradient, width, start, end, c1, c2); if (b1) { - for (int i2 = mid, i = 0; i < size; i2++, i++) { + // Regswaps here + for (int i2 = mid, i = 0; i < width; i2++, i++) { colors[i].r = gradient[i < mid ? i2 : i - mid].r; colors[i].g = gradient[i < mid ? i2 : i - mid].g; colors[i].b = gradient[i < mid ? i2 : i - mid].b; colors[i].a = gradient[i < mid ? i2 : i - mid].a; } - for (int i = 0; i < size; i++) { + for (int i = 0; i < width; i++) { gradient[i] = colors[i]; } } u16 start2 = b2 ? 0 : start; - u16 end2 = b2 ? size : end; - + u32 end2 = b2 ? width : end; for (u16 x = start2; x < end2; x++) { for (u16 y = 0; y < height; y++) { if (swapMode) { @@ -274,13 +274,19 @@ void CpuTexture::allocWithHeaderDebug(Heap *pHeap) { 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; + int pix = (x & 0x3) * 2 + (y & 0x3) * 8; + int block = (x >> 2) + (y >> 2) * (getWidth() / 4); + + int offset = block * 0x40 + pix; + u8 *dat = static_cast(getBuffer()) + offset; + dat[0] = color.a; dat[1] = color.r; dat[0x20] = color.g; @@ -289,17 +295,30 @@ void CpuTexture::setColor(u16 x, u16 y, GXColor color) { } case GX_TF_I8: case GX_TF_Z8: { - // TODO - int offset = ((x >> 3) + (y >> 2) * (getWidth() / 8)) * 0x20 + (y & 3) * 8 + (x & 7); - u8 *dat = static_cast(getBuffer()) + offset; + // Regswaps here + int pix = (x & 0x7); + int pix_y = (y & 0x3) * 8; + + int block = (x >> 3); + int block_y = (y >> 2) * (getWidth() / 8); + + pix = pix + pix_y + (block + block_y) * 0x20; + + u8 *dat = static_cast(getBuffer()) + pix; 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; + int block = (x >> 2) + (y >> 2) * (getWidth() / 4); + int pix = (x & 0x3) * 2 + (y & 0x3) * 8; + + int offset = block * 0x20 + pix; + u8 *dat = static_cast(getBuffer()) + offset; + dat[0] = color.a; dat[1] = color.r; break; @@ -324,9 +343,11 @@ GXColor CpuTexture::getColor(u16 x, u16 y) const { } case GX_TF_I8: case GX_TF_Z8: { - // TODO - int offset = ((x >> 3) + (y >> 2) * (getWidth() / 8)) * 0x20 + (y & 3) * 8 + (x & 7); - u8 *dat = static_cast(getBuffer()) + offset; + int idx = (x & 0x7); + int pixel_idx = (y & 0x3) * 8; + int block_idx = ((getWidth() / 8) * (y >> 2) + (x >> 3)); + idx = idx + pixel_idx + block_idx * 0x20; + u8 *dat = static_cast(getBuffer()) + idx; c.a = dat[0]; c.b = dat[0]; c.g = dat[0]; From 3df431e4f0c7c11f09d8d1f8dfa16823e38b1ac7 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sun, 30 Mar 2025 01:25:13 -0400 Subject: [PATCH 58/62] Frustum Fix 1 --- src/egg/gfx/eggFrustum.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/egg/gfx/eggFrustum.cpp b/src/egg/gfx/eggFrustum.cpp index d7c9e039..59eafd69 100644 --- a/src/egg/gfx/eggFrustum.cpp +++ b/src/egg/gfx/eggFrustum.cpp @@ -4,7 +4,6 @@ #include "egg/gfx/eggStateGX.h" #include "nw4r/math/math_arithmetic.h" - void eggFrustum_float_ordering() { 1.0f; } @@ -201,12 +200,12 @@ void Frustum::GetOrthographicParam_(f32 *p) const { f32 invHor = 1.0f / (r - l); f32 invVert = 1.0f / (t - b); f32 invZ = 1.0f / (mFarZ - mNearZ); - + p[0] = 1.0f; p[1] = invHor * 2.0f; - p[3] = invVert * 2.0f; - p[2] = invHor * -(r + l); + p[3] = invVert * 2.0f; + p[4] = invVert * -(t + b); p[5] = -1.0f * invZ; p[6] = -mFarZ * invZ; From 772a0d56bbff35e85293cf75654e5389708cf09b Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sun, 30 Mar 2025 15:00:55 -0400 Subject: [PATCH 59/62] LightTexture::fn_804AC0E0 and LightTexture::addLight fix --- include/egg/gfx/eggDrawGX.h | 5 +++++ src/egg/gfx/eggLightTexture.cpp | 23 +++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/include/egg/gfx/eggDrawGX.h b/include/egg/gfx/eggDrawGX.h index 7a4056b6..33d5e37a 100644 --- a/include/egg/gfx/eggDrawGX.h +++ b/include/egg/gfx/eggDrawGX.h @@ -158,6 +158,11 @@ public: } // TODO MORE + static void SetTevColor(GXTevRegID regId, GXColor tevClr, GXTevKColorID colorId, GXColor tevkClr) { + GXSetTevColor(regId, tevClr); + GXSetTevKColor(colorId, tevkClr); + } + // not sure static DLData s_DL[DL_MAX]; static const DL s_DL0; diff --git a/src/egg/gfx/eggLightTexture.cpp b/src/egg/gfx/eggLightTexture.cpp index 428dbea9..fe00914b 100644 --- a/src/egg/gfx/eggLightTexture.cpp +++ b/src/egg/gfx/eggLightTexture.cpp @@ -396,9 +396,10 @@ void LightTexture::fn_804AC0E0(int i, const GXColor &color, bool b) { int remainder = field_0x9F % field_0x9D; if (remainder > 0) { for (; remainder < field_0x9D; remainder++) { - // TODO: color stack slots swapped - GXSetTevColor(static_cast(GX_TEVREG0 + remainder), DrawGX::BLACK); - GXSetTevKColor(static_cast(GX_KCOLOR0 + remainder), DrawGX::BLACK); + DrawGX::SetTevColor( + static_cast(GX_TEVREG0 + remainder), DrawGX::BLACK, + static_cast(GX_KCOLOR0 + remainder), DrawGX::BLACK + ); } f32 origin = GetLightType() != 2 ? 0.0f : 0.5f; @@ -537,7 +538,6 @@ void LightTexture::debugDraw(int i) { } void LightTexture::addLight(const EGG::LightObject &obj) { - // NONMATCHING if (!(obj.CheckFlag1() && obj.CheckFlag0x20() && (mpByteData1[obj.GetIndex()] & 1) != 0 && (field_0x9F < 2 || mLightType != 1))) { return; @@ -552,14 +552,13 @@ void LightTexture::addLight(const EGG::LightObject &obj) { } sCpuTexArray[mpByteData2[obj.GetIndex()]]->load(static_cast(field_0x9E + remainder)); - // TODO - GXColor blackColor = obj.GetBlack(); - // Sorry clang-format, what is this formatting??? - blackColor = (GXColor - ){blackColor.r * obj.getField0x30(), blackColor.g * obj.getField0x30(), blackColor.b * obj.getField0x30(), - blackColor.a}; - GXSetTevColor(static_cast(GX_TEVREG0 + remainder), color); - GXSetTevKColor(static_cast(GX_KCOLOR0 + remainder), blackColor); + GXColor blk = obj.GetBlack(); + f32 mult = obj.getField0x30(); + blk = (GXColor){blk.r * mult, blk.g * mult, blk.b * mult, obj.GetBlack().a}; + + DrawGX::SetTevColor( + static_cast(GX_TEVREG0 + remainder), color, static_cast(GX_KCOLOR0 + remainder), blk + ); if (GetLightType() == 0 || GetLightType() == 2) { f32 mtx[2][3]; mtx[0][0] = -vec.x * 0.485f; From 5f8c997d9d40d0cfee9d0367be514577d773d90d Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sun, 30 Mar 2025 15:12:23 -0400 Subject: [PATCH 60/62] Update eggLightObject.cpp --- src/egg/gfx/eggLightObject.cpp | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/egg/gfx/eggLightObject.cpp b/src/egg/gfx/eggLightObject.cpp index b19e3a0f..d1d63711 100644 --- a/src/egg/gfx/eggLightObject.cpp +++ b/src/egg/gfx/eggLightObject.cpp @@ -88,28 +88,18 @@ void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) { if (getField0x3C() < 0 || getField0x3C() > 1) { switch (getField0x3C()) { case 3: { - // Halp - f32 scale = -1.0f; - mViewAt.x = 0.0f; - field_0x94.x = 0.0f; - mViewAt.y = 0.0f; - field_0x94.y = 0.0f; - field_0x94.z = -1.0f; - mViewAt.z = scale * mDist; - mViewPos.z = 0.0f; - mViewPos.y = 0.0f; - mViewPos.x = 0.0f; + field_0x94.x = mViewAt.x = 0.0f; + field_0x94.y = mViewAt.y = 0.0f; + field_0x94.z = mViewAt.z = -1.0f; + mViewAt.z *= mDist; + mViewPos.x = mViewPos.y = mViewPos.z = 0.0f; break; } case 4: { - // Halp - f32 scale = 1.0f; - mViewPos.x = 0.0f; - field_0x94.x = 0.0f; - mViewPos.y = 0.0f; - field_0x94.y = 0.0f; - field_0x94.z = 1.0f; - mViewPos.z = scale * mDist; + field_0x94.x = mViewPos.x = 0.0f; + field_0x94.y = mViewPos.y = 0.0f; + field_0x94.z = mViewPos.z = 1.0f; + mViewPos.z *= mDist; mViewAt.z = 0.0f; mViewAt.y = 0.0f; mViewAt.x = 0.0f; @@ -240,7 +230,7 @@ void LightObject::CopyToG3D_View(nw4r::g3d::LightObj &g3dObj, const nw4r::math:: } // TODO - if (!(mFlags & 0x800)) { + if (!((mFlags >> 11) & 1)) { nw4r::math::VEC3 dir; nw4r::math::VEC3 pos; switch (field_0x3D) { From 0913f060546f19b03b1e8849e75ee869def77a49 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sun, 30 Mar 2025 15:26:26 -0400 Subject: [PATCH 61/62] brief lightObject cleanup --- include/egg/gfx/eggLightObject.h | 9 ++-- src/egg/gfx/eggLightObject.cpp | 81 +++++++++++++------------------- 2 files changed, 37 insertions(+), 53 deletions(-) diff --git a/include/egg/gfx/eggLightObject.h b/include/egg/gfx/eggLightObject.h index b2cc876c..a072e190 100644 --- a/include/egg/gfx/eggLightObject.h +++ b/include/egg/gfx/eggLightObject.h @@ -125,12 +125,11 @@ public: void UpdatePosAt(LightObject &other) { SetPosAt(other.mPos, other.mAt); } - + const GXColor &GetBlack() const { return mBlack; } - private: /* 0x04 */ u16 mIndex; /* 0x06 */ u16 field_0x06; @@ -145,9 +144,9 @@ private: /* 0x3D */ u8 field_0x3D; /* 0x3E */ u8 mSpotFn; /* 0x3F */ u8 mDistAttnFn; - /* 0x40 */ f32 field_0x40; - /* 0x44 */ f32 field_0x44; - /* 0x48 */ f32 field_0x48; + /* 0x40 */ f32 mCutoff; + /* 0x44 */ f32 mRefDist; + /* 0x48 */ f32 mRefBrightness; /* 0x4C */ nw4r::math::VEC3 field_0x4C; /* 0x58 */ nw4r::math::VEC3 field_0x58; /* 0x64 */ f32 mShininess; diff --git a/src/egg/gfx/eggLightObject.cpp b/src/egg/gfx/eggLightObject.cpp index d1d63711..baf6a6a8 100644 --- a/src/egg/gfx/eggLightObject.cpp +++ b/src/egg/gfx/eggLightObject.cpp @@ -47,9 +47,9 @@ LightObject::LightObject() field_0x3D(1), mSpotFn(GX_SP_OFF), mDistAttnFn(GX_DA_OFF), - field_0x40(90.0f), - field_0x44(0.5f), - field_0x48(0.5f), + mCutoff(90.0f), + mRefDist(0.5f), + mRefBrightness(0.5f), mShininess(16.0f), mFlags(0x661) {} @@ -61,18 +61,16 @@ void LightObject::Reset() { field_0x30 = 1.0; field_0x3C = 0; field_0x3D = 1; - field_0x40 = 90.0; - field_0x44 = 0.5; - field_0x48 = 0.5; + mCutoff = 90.0; + mRefDist = 0.5; + mRefBrightness = 0.5; mSpotFn = GX_SP_OFF; mDistAttnFn = GX_DA_OFF; mShininess = 16.0; - field_0x58.x = 1.0; - field_0x4C.x = 1.0; - field_0x58.z = 0.0; - field_0x4C.z = 0.0; - field_0x58.y = 0.0; - field_0x4C.y = 0.0; + + field_0x4C.x = field_0x58.x = 1.0f; + field_0x4C.z = field_0x58.z = 0.0f; + field_0x4C.y = field_0x58.y = 0.0f; } void LightObject::Calc() { @@ -100,9 +98,7 @@ void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) { field_0x94.y = mViewPos.y = 0.0f; field_0x94.z = mViewPos.z = 1.0f; mViewPos.z *= mDist; - mViewAt.z = 0.0f; - mViewAt.y = 0.0f; - mViewAt.x = 0.0f; + mViewAt.x = mViewAt.y = mViewAt.z = 0.0f; break; } case 2: @@ -121,8 +117,7 @@ void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) { nw4r::math::VEC3Scale(&field_0x6C, &angle, -1.0f); PSVECNormalize(field_0x6C, field_0x6C); } else { - field_0x6C.y = 0.0f; - field_0x6C.x = 0.0f; + field_0x6C.x = field_0x6C.y = 0.0f; field_0x6C.z = 1.0f; } } @@ -172,13 +167,13 @@ void LightObject::InitGX(GXLightObj *obj) const { if ((mFlags & 0x80) != 0) { GXInitLightAttnA(obj, field_0x4C.x, field_0x4C.y, field_0x4C.z); } else { - GXInitLightSpot(obj, field_0x40 > 0.0f ? field_0x40 : 0.0001f, getSpotFn()); + GXInitLightSpot(obj, mCutoff > 0.0f ? mCutoff : 0.0001f, getSpotFn()); } if ((mFlags & 0x100) != 0) { GXInitLightAttnK(obj, field_0x58.x, field_0x58.y, field_0x58.z); } else { - GXInitLightDistAttn(obj, field_0x44 * getDistance(), field_0x48, getDistAttnFn()); + GXInitLightDistAttn(obj, mRefDist * getDistance(), mRefBrightness, getDistAttnFn()); } if ((mFlags & 0x800) != 0) { @@ -207,13 +202,13 @@ void LightObject::CopyToG3D_World(nw4r::g3d::LightObj &g3dObj) const { if ((mFlags & 0x80) != 0) { g3dObj.InitLightAttnA(field_0x4C.x, field_0x4C.y, field_0x4C.z); } else { - g3dObj.InitLightSpot(field_0x40 > 0.0f ? field_0x40 : 0.0001f, getSpotFn()); + g3dObj.InitLightSpot(mCutoff > 0.0f ? mCutoff : 0.0001f, getSpotFn()); } if ((mFlags & 0x100) != 0) { g3dObj.InitLightAttnK(field_0x58.x, field_0x58.y, field_0x58.z); } else { - g3dObj.InitLightDistAttn(field_0x44 * getDistance(), field_0x48, getDistAttnFn()); + g3dObj.InitLightDistAttn(mRefDist * getDistance(), mRefBrightness, getDistAttnFn()); } if ((mFlags & 0x800) != 0) { @@ -229,7 +224,6 @@ void LightObject::CopyToG3D_View(nw4r::g3d::LightObj &g3dObj, const nw4r::math:: return; } - // TODO if (!((mFlags >> 11) & 1)) { nw4r::math::VEC3 dir; nw4r::math::VEC3 pos; @@ -237,16 +231,12 @@ void LightObject::CopyToG3D_View(nw4r::g3d::LightObj &g3dObj, const nw4r::math:: case 1: { nw4r::math::VEC3TransformNormal(&dir, &viewMtx, &field_0x94); nw4r::math::VEC3Scale(&pos, &dir, -1e10f); - dir.z = 0.0f; - dir.y = 0.0f; - dir.x = 0.0f; + dir.x = dir.y = dir.z = 0.0f; break; } case 0: { PSMTXMultVec(viewMtx, mViewPos, pos); - dir.z = 0.0f; - dir.y = 0.0f; - dir.x = 0.0f; + dir.x = dir.y = dir.z = 0.0f; break; } case 2: { @@ -275,7 +265,6 @@ void LightObject::CopyFromG3D( optObj->mFlags |= 2; } } else { - // TODO ClearFlag2(); if (optObj != nullptr) { optObj->ClearFlag2(); @@ -287,19 +276,17 @@ void LightObject::CopyFromG3D( void LightObject::ApplyAnmResultInner(const nw4r::g3d::LightAnmResult &res) { // TODO mFlags = mFlags & 0xF07E; - field_0x40 = 90.0f; - field_0x44 = 0.5f; - field_0x48 = 0.5f; + mCutoff = 90.0f; + mRefDist = 0.5f; + mRefBrightness = 0.5f; mSpotFn = GX_SP_OFF; mDistAttnFn = GX_DA_OFF; mShininess = 16.0f; - // ... - field_0x58.x = 1.0f; - field_0x4C.x = 1.0f; - field_0x58.z = 0.0f; - field_0x4C.z = 0.0f; - field_0x58.y = 0.0f; - field_0x4C.y = 0.0f; + + field_0x4C.x = field_0x58.x = 1.0f; + field_0x4C.z = field_0x58.z = 0.0f; + field_0x4C.y = field_0x58.y = 0.0f; + if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_COLOR_ENABLE) != 0) { mFlags |= 0x200; } @@ -318,10 +305,10 @@ void LightObject::ApplyAnmResultA(const nw4r::g3d::LightAnmResult &res) { field_0x3D = 0; mWhite = res.color; SetPosAt(res.pos, res.pos); - field_0x40 = 0.0f; + mCutoff = 0.0f; mSpotFn = GX_SP_OFF; - field_0x44 = res.refDistance; - field_0x48 = res.refBrightness; + mRefDist = res.refDistance; + mRefBrightness = res.refBrightness; mDistAttnFn = res.distFunc; break; } @@ -338,10 +325,10 @@ void LightObject::ApplyAnmResultA(const nw4r::g3d::LightAnmResult &res) { mWhite = res.color; SetPosAt(res.pos, res.aim); mSpotFn = res.spotFunc; - field_0x40 = res.cutoff; + mCutoff = res.cutoff; mDistAttnFn = res.distFunc; - field_0x44 = res.refDistance; - field_0x48 = res.refBrightness; + mRefDist = res.refDistance; + mRefBrightness = res.refBrightness; break; } } @@ -370,9 +357,7 @@ void LightObject::CalcDirDist() { if (mDist > 0.0f) { nw4r::math::VEC3Scale(&mDir, &mDir, 1.0f / nw4r::math::FSqrt(mDist)); } else { - mDir.z = 0.0f; - mDir.y = 0.0f; - mDir.x = 0.0f; + mDir.x = mDir.y = mDir.z = 0.0f; } } From 81574f0ff1d96865383bf3b4f75ed4dac09842b0 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sun, 30 Mar 2025 17:28:11 -0400 Subject: [PATCH 62/62] LightTexture OK --- configure.py | 2 +- include/egg/gfx/eggLightTexture.h | 49 +++++++----- src/egg/gfx/eggLightTexture.cpp | 126 +++++++++++++++++++++++++++++- 3 files changed, 154 insertions(+), 23 deletions(-) diff --git a/configure.py b/configure.py index 8b0a546e..a4cf29a7 100644 --- a/configure.py +++ b/configure.py @@ -886,7 +886,7 @@ config.libs = [ Object(Matching, "egg/gfx/eggIScnProc.cpp"), Object(NonMatching, "egg/gfx/eggLightManager.cpp"), Object(NonMatching, "egg/gfx/eggLightObject.cpp"), - Object(NonMatching, "egg/gfx/eggLightTexture.cpp"), + Object(Matching, "egg/gfx/eggLightTexture.cpp"), Object(Matching, "egg/gfx/eggLightTextureMgr.cpp"), Object(Matching, "egg/gfx/eggModelEx.cpp"), Object(Matching, "egg/gfx/eggPostEffectBase.cpp"), diff --git a/include/egg/gfx/eggLightTexture.h b/include/egg/gfx/eggLightTexture.h index c79db857..ef441058 100644 --- a/include/egg/gfx/eggLightTexture.h +++ b/include/egg/gfx/eggLightTexture.h @@ -32,7 +32,7 @@ public: /* 0x24 */ u8 mType; /* 0x25 */ u16 field_0x25; /* 0x27 */ u8 field_0x27; - /* 0x28 */ u8 _0x28[4]; + /* 0x28 */ u32 field_0x28; /* 0x2C */ f32 field_0x2C; /* 0x30 */ u8 _0x30[4]; /* 0x34 */ char mName2[32]; @@ -54,9 +54,9 @@ public: static void initialize(u16 textureSize, Heap *pHeap); static void loadTextureFromResTimg(int index, EGG::ResTIMG *img); static void initDrawSetting(u16, u16, u16, u16); - void addLight(const EGG::LightObject&); + void addLight(const EGG::LightObject &); - void fn_804AC0E0(int, const GXColor&, bool); + void fn_804AC0E0(int, const GXColor &, bool); void draw(int); static void beginDebugDraw(); void debugDraw(int); @@ -64,30 +64,41 @@ public: const char *getName() const { return mName1; } - + f32 getFloat(u16 idx) const { return mpFloatData[idx]; } - - static void getTexDimensions(u16*, u16*, u16*, u16*, u16); - -private: - - static void fn_804AB270(); - static void fn_804AB310(const GXColor &color); - static void fn_804AB440(); - static void fn_804AB600(); - - static void fn_804AC0A0(int, int*, int*); - static void loadTextureData(int index, void *data, GXTexFmt fmt); + void setFloat(u16 idx, f32 val) { + mpFloatData[idx] = val; + } u8 getByte1(u16 idx) const { return mpByteData1[idx]; } + void offByte1(u16 idx) { + mpByteData1[idx] &= ~1; + } + void onByte1(u16 idx) { + mpByteData1[idx] |= 1; + } u8 getByte2(u16 idx) const { return mpByteData2[idx]; } + void setByte2(u16 idx, u8 val) const { + mpByteData2[idx] = val; + } + + static void getTexDimensions(u16 *, u16 *, u16 *, u16 *, u16); + +private: + static void fn_804AB270(); + static void fn_804AB310(const GXColor &color); + static void fn_804AB440(); + static void fn_804AB600(); + + static void fn_804AC0A0(int, int *, int *); + static void loadTextureData(int index, void *data, GXTexFmt fmt); // TODO enum int GetLightType() const { @@ -101,12 +112,12 @@ private: /* 0x37 */ u8 mLightType; /* 0x38 */ Vector3f field_0x38; /* 0x44 */ f32 *mpFloatData; - /* 0x48 */ char *mpByteData1; + /* 0x48 */ u8 *mpByteData1; /* 0x4C */ u8 *mpByteData2; /* 0x50 */ f32 field_0x50; /* 0x54 */ char mName1[0x20]; /* 0x74 */ char mName2[0x20]; - /* 0x94 */ u16 field_0x94; + /* 0x94 */ s16 field_0x94; /* 0x98 */ f32 field_0x98; /* 0x9C */ u8 field_0x9C; /* 0x9D */ u8 field_0x9D; @@ -114,7 +125,7 @@ private: /* 0x9F */ u8 field_0x9F; static u16 sTextureSize; - + static u16 sDrawWidth; static u16 sDrawHeight; static u16 sDrawPosX; diff --git a/src/egg/gfx/eggLightTexture.cpp b/src/egg/gfx/eggLightTexture.cpp index fe00914b..114da7da 100644 --- a/src/egg/gfx/eggLightTexture.cpp +++ b/src/egg/gfx/eggLightTexture.cpp @@ -227,7 +227,7 @@ LightTexture::LightTexture(const char *name, const LightTextureManager *mgr) } field_0x9C = 0; mpFloatData = new float[mNumData]; - mpByteData1 = new char[mNumData]; + mpByteData1 = new u8[mNumData]; mpByteData2 = new u8[mNumData]; for (int i = 0; i < mNumData; i++) { mpByteData2[i] = 0; @@ -590,9 +590,129 @@ void LightTexture::addLight(const EGG::LightObject &obj) { field_0x9F++; } - void LightTexture::SetBinaryInner(const Bin &bin) { - // TODO + switch (bin.mHeader.mVersion) { + case 0: { + const struct Data { + /* 0x00 */ u16 mNumEntries; + /* 0x02 */ u8 _pad_02[2]; + /* 0x04 */ char mName[32]; + /* 0x24 */ u8 mType; + /* 0x25 */ u8 _pad_25[3]; + /* 0x28 */ u32 field_0x28; + /* 0x2C */ SubData mSubData[1]; + } &data = *(const Data *)&bin.mData; + mLightType = data.mType; + int numData = (u16)MIN(data.mNumEntries, (u16)mNumData); + + const SubData *pSub = data.mSubData; + for (int i = 0; numData > 0; numData--, i++, pSub++) { + if (data.field_0x28 & (1 << i)) { + onByte1(i); + } else { + offByte1(i); + } + setFloat(i, pSub->mIntensity); + setByte2(i, pSub->mGradientUsed); + } + + field_0x35 = 0; + field_0x50 = 1.f; + field_0x36 &= ~1; + field_0x36 &= ~2; + mName2[0] = '\0'; + field_0x94 = -1; + + } break; + case 1: + case 2: { + const struct Data { + /* 0x00 */ u16 mNumEntries; + /* 0x02 */ u8 field_0x02; + /* 0x03 */ u8 field_0x03; + /* 0x04 */ char mName[32]; + /* 0x24 */ u8 mType; + /* 0x25 */ u8 _pad_25[3]; + /* 0x28 */ u32 field_0x28; + /* 0x2C */ f32 field_0x2C; + /* 0x30 */ u8 _30[8]; + /* 0x38 */ SubData mSubData[1]; + } &data = *(const Data *)&bin.mData; + + mLightType = data.mType; + int numData = (u16)MIN(data.mNumEntries, (u16)mNumData); + + const SubData *pSub = data.mSubData; + for (int i = 0; numData > 0; numData--, i++, pSub++) { + if (bin.mHeader.mVersion == 1) { + if (data.field_0x28 & (1 << i)) { + onByte1(i); + } else { + offByte1(i); + } + } else if (pSub->field_0x05 & 1) { + onByte1(i); + } else { + offByte1(i); + } + setFloat(i, pSub->mIntensity); + setByte2(i, pSub->mGradientUsed); + } + + if (data.field_0x02 & 1) { + field_0x36 |= 1; + } else { + field_0x36 &= ~1; + } + + field_0x35 = data.field_0x03; + field_0x50 = data.field_0x2C; + field_0x36 &= ~2; + mName2[0] = '\0'; + field_0x94 = -1; + field_0x98 = 1.f; + + } break; + case 3: { + const BinData &data = bin.mData; + mLightType = data.mType; + int numData = (u16)MIN(data.mNumEntries, (u16)mNumData); + + const SubData *pSub = data.mSubData; + for (int i = 0; numData > 0; numData--, i++, pSub++) { + if (bin.mHeader.mVersion == 1) { + if (data.field_0x28 & (1 << i)) { + onByte1(i); + } else { + offByte1(i); + } + } else if (pSub->field_0x05 & 1) { + onByte1(i); + } else { + offByte1(i); + } + setFloat(i, pSub->mIntensity); + setByte2(i, pSub->mGradientUsed); + } + + if (data.field_0x02 & 1) { + field_0x36 |= 1; + } else { + field_0x36 &= ~1; + } + field_0x35 = data.field_0x03; + field_0x50 = data.field_0x2C; + + if (data.field_0x02 & 2) { + field_0x36 |= 2; + } else { + field_0x36 &= ~2; + } + std::strcpy(mName2, data.mName2); + field_0x94 = -1; + field_0x98 = data.field_0x54; + } break; + } } void LightTexture::GetBinaryInner(Bin *pOutBin) const {