From d35c4adeeffc0629f705518aedd9e8d4b4570364 Mon Sep 17 00:00:00 2001 From: robojumper Date: Fri, 28 Mar 2025 18:42:09 +0100 Subject: [PATCH] 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()) {