diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index e64d6945..d99e2921 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/configure.py b/configure.py index c681fdd7..b0f4d003 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/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/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]; } 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; } }