From 3c90e916b962f54a25d9cf4d404675a819ff3c1b Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 22 Mar 2025 01:10:41 +0100 Subject: [PATCH] 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