From 818e818b56af7584c2f9b8274f68a2ff664605e3 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Fri, 21 Mar 2025 21:09:54 -0400 Subject: [PATCH] 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(