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