From f508e9f6c567f0ebd510f60a887261e0bec3de5f Mon Sep 17 00:00:00 2001 From: Roman Sandu Date: Thu, 6 Feb 2025 23:54:17 +0300 Subject: [PATCH] Match J3DColorBlock & frens (thx tww) --- .../J3D/J3DGraphBase/J3DColorBlocks.hpp | 153 ++++++++++++++++++ .../J3D/J3DGraphBase/J3DComponents.hpp | 44 +++++ include/JSystem/J3D/J3DGraphBase/J3DTevs.hpp | 19 ++- src/JSystem/J3D/J3DGraphBase/J3DMaterial.cpp | 102 ++++++++++++ src/JSystem/J3D/J3DGraphBase/J3DTevs.cpp | 9 +- 5 files changed, 317 insertions(+), 10 deletions(-) create mode 100644 include/JSystem/J3D/J3DGraphBase/J3DColorBlocks.hpp diff --git a/include/JSystem/J3D/J3DGraphBase/J3DColorBlocks.hpp b/include/JSystem/J3D/J3DGraphBase/J3DColorBlocks.hpp new file mode 100644 index 00000000..f4cea377 --- /dev/null +++ b/include/JSystem/J3D/J3DGraphBase/J3DColorBlocks.hpp @@ -0,0 +1,153 @@ +#ifndef J3D_COLOR_BLOCKS_HPP +#define J3D_COLOR_BLOCKS_HPP + +#include +#include + +class J3DColorBlock { +public: + virtual void reset(J3DColorBlock*) { } + virtual s32 countDLSize() = 0; + virtual u32 getType() = 0; + + virtual void setMatColor(u32, const J3DGXColor*) = 0; + virtual void setMatColor(u32, J3DGXColor) = 0; + virtual J3DGXColor* getMatColor(u32) = 0; + + virtual void setAmbColor(u32, const J3DGXColor*) = 0; + virtual void setAmbColor(u32, J3DGXColor) = 0; + virtual J3DGXColor* getAmbColor(u32) = 0; + + virtual void setColorChanNum(u8) = 0; + virtual void setColorChanNum(const u8*) = 0; + virtual u8 getColorChanNum() const = 0; + + virtual void setColorChan(u32, const J3DColorChan&) = 0; + virtual void setColorChan(u32, const J3DColorChan*) = 0; + virtual J3DColorChan* getColorChan(u32) = 0; + + virtual void setLight(u32, J3DLightObj*) = 0; + virtual J3DLightObj* replaceLight(u32, J3DLightObj*) = 0; + virtual J3DLightObj* getLight(u32) = 0; + + virtual void setCullMode(const u8*) = 0; + virtual void setCullMode(u8) = 0; + virtual u8 getCullMode() const = 0; + + virtual ~J3DColorBlock() { } + virtual void load() = 0; +}; + +class J3DColorBlockLightOff : public J3DColorBlock { +public: + void initialize(); + + virtual void reset(J3DColorBlock*); + virtual s32 countDLSize(); + virtual u32 getType() { return 'CLOF'; } + + virtual void setMatColor(u32 i, const J3DGXColor* color) + { + mMatColor[i] = *color; + } + virtual void setMatColor(u32 i, J3DGXColor color) { mMatColor[i] = color; } + virtual J3DGXColor* getMatColor(u32 i) { return &mMatColor[i]; } + + virtual void setAmbColor(u32, const J3DGXColor*) { } + virtual void setAmbColor(u32, J3DGXColor) { } + virtual J3DGXColor* getAmbColor(u32) { return nullptr; } + + virtual void setColorChanNum(u8 num) { mColorChanNum = num; } + virtual void setColorChanNum(const u8* num) { mColorChanNum = *num; } + virtual u8 getColorChanNum() const { return mColorChanNum; } + + virtual void setColorChan(u32 i, const J3DColorChan& chan) + { + mColorChan[i] = chan; + } + virtual void setColorChan(u32 i, const J3DColorChan* chan) + { + mColorChan[i] = *chan; + } + virtual J3DColorChan* getColorChan(u32 i) { return &mColorChan[i]; } + + virtual void setLight(u32, J3DLightObj*) { } + virtual J3DLightObj* replaceLight(u32, J3DLightObj*) { return nullptr; } + virtual J3DLightObj* getLight(u32) { return nullptr; } + + virtual void setCullMode(const u8* mode) { mCullMode = *mode; } + virtual void setCullMode(u8 mode) { mCullMode = mode; } + virtual u8 getCullMode() const { return mCullMode; } + + virtual ~J3DColorBlockLightOff() { } + virtual void load(); + +private: + /* 0x04 */ J3DGXColor mMatColor[2]; + /* 0x0C */ u8 mColorChanNum; + /* 0x0E */ J3DColorChan mColorChan[4]; + /* 0x16 */ u8 mCullMode; +}; + +class J3DColorBlockLightOn : public J3DColorBlock { +public: + void initialize(); + + virtual void reset(J3DColorBlock*); + virtual s32 countDLSize(); + virtual u32 getType() { return 'CLON'; } + + virtual void setMatColor(u32 i, const J3DGXColor* color) + { + mMatColor[i] = *color; + } + virtual void setMatColor(u32 i, J3DGXColor color) { mMatColor[i] = color; } + virtual J3DGXColor* getMatColor(u32 i) { return &mMatColor[i]; } + + virtual void setAmbColor(u32 i, const J3DGXColor* color) + { + mAmbColor[i] = *color; + } + virtual void setAmbColor(u32 i, J3DGXColor color) { mAmbColor[i] = color; } + virtual J3DGXColor* getAmbColor(u32 i) { return &mAmbColor[i]; } + + virtual void setColorChanNum(u8 num) { mColorChanNum = num; } + virtual void setColorChanNum(const u8* num) { mColorChanNum = *num; } + virtual u8 getColorChanNum() const { return mColorChanNum; } + + virtual void setColorChan(u32 i, const J3DColorChan& chan) + { + mColorChan[i] = chan; + } + virtual void setColorChan(u32 i, const J3DColorChan* chan) + { + mColorChan[i] = *chan; + } + virtual J3DColorChan* getColorChan(u32 i) { return &mColorChan[i]; } + + virtual void setLight(u32 i, J3DLightObj* light) { mLight[i] = light; } + virtual J3DLightObj* replaceLight(u32 i, J3DLightObj* light) + { + J3DLightObj* ret = mLight[i]; + mLight[i] = light; + return ret; + } + virtual J3DLightObj* getLight(u32 i) { return mLight[i]; } + + virtual void setCullMode(const u8* mode) { mCullMode = *mode; } + virtual void setCullMode(u8 mode) { mCullMode = mode; } + virtual u8 getCullMode() const { return mCullMode; } + + virtual ~J3DColorBlockLightOn() { } + virtual void load(); + +public: + /* 0x04 */ J3DGXColor mMatColor[2]; + /* 0x0C */ J3DGXColor mAmbColor[2]; + /* 0x14 */ u8 mColorChanNum; + /* 0x16 */ J3DColorChan mColorChan[4]; + /* 0x20 */ J3DLightObj* mLight[8]; + /* 0x40 */ u8 mCullMode; +}; + +#endif diff --git a/include/JSystem/J3D/J3DGraphBase/J3DComponents.hpp b/include/JSystem/J3D/J3DGraphBase/J3DComponents.hpp index 1fb1f3c5..54de88b8 100644 --- a/include/JSystem/J3D/J3DGraphBase/J3DComponents.hpp +++ b/include/JSystem/J3D/J3DGraphBase/J3DComponents.hpp @@ -260,4 +260,48 @@ class J3DZMode { u16 mZModeID; }; +inline u32 setChanCtrlMacro(u8 enable, GXColorSrc ambSrc, GXColorSrc matSrc, + u32 lightMask, GXDiffuseFn diffuseFn, + GXAttnFn attnFn) +{ + u32 ret = matSrc << 0; // Putting this as a separate statement fixes + // codegen, but regalloc is still wrong + return ret | enable << 1 | (lightMask & 0x0F) << 2 | ambSrc << 6 + | ((attnFn == GX_AF_SPEC) ? GX_DF_NONE : diffuseFn) << 7 + | (attnFn != GX_AF_NONE) << 9 | (attnFn != GX_AF_SPEC) << 10 + | (lightMask >> 4 & 0x0F) << 11; +} + +struct J3DColorChan { + J3DColorChan& operator=(const J3DColorChan& other) + { + mChanCtrl = other.mChanCtrl; + return *this; + } + + GXAttnFn getAttnFn() + { + u8 attnFnTbl[] = { GX_AF_NONE, GX_AF_SPEC, GX_AF_NONE, GX_AF_SPOT }; + return (GXAttnFn)attnFnTbl[mChanCtrl >> 9 & 0x03]; + } + GXDiffuseFn getDiffuseFn() { return (GXDiffuseFn)(mChanCtrl >> 7 & 3); } + u8 getLightMask() + { + return (mChanCtrl >> 2 & 0x0F) | (mChanCtrl >> 11 & 0x0f) << 4; + } + GXColorSrc getMatSrc() { return (GXColorSrc)(mChanCtrl >> 0 & 1); } + GXColorSrc getAmbSrc() { return (GXColorSrc)(mChanCtrl >> 6 & 1); } + u8 getEnable() { return (mChanCtrl >> 1) & 1; } + + void load(u32 chan) + { + const GXChannelID chanTbl[] + = { GX_COLOR0, GX_ALPHA0, GX_COLOR1, GX_ALPHA1 }; + J3DGDSetChanCtrl(chanTbl[chan], getEnable(), getAmbSrc(), getMatSrc(), + getLightMask(), getDiffuseFn(), getAttnFn()); + } + + /* 0x0 */ u16 mChanCtrl; +}; + #endif diff --git a/include/JSystem/J3D/J3DGraphBase/J3DTevs.hpp b/include/JSystem/J3D/J3DGraphBase/J3DTevs.hpp index 3614a9cb..81ae1a9f 100644 --- a/include/JSystem/J3D/J3DGraphBase/J3DTevs.hpp +++ b/include/JSystem/J3D/J3DGraphBase/J3DTevs.hpp @@ -41,14 +41,21 @@ void J3DLoadCPCmd(u8, u32); void J3DLoadArrayBasePtr(GXAttr, void*); void J3DSetVtxAttrFmtv(GXVtxFmt, GXVtxAttrFmtList*, bool); -struct J3DLightObj { +class J3DLightObj : public J3DLightInfo { +public: + J3DLightObj() { setDefault(); } + + // Completely made up to force J3DLightInfo::operator= to NOT inline + void setDefault() { setInfo(j3dDefaultLightInfo); } + void setInfo(const J3DLightInfo& info) + { + J3DLightInfo::operator=(j3dDefaultLightInfo); + } + void load(u32) const; - Vec mPos; - Vec mDir; - GXColor mColor; - Vec mAttnA; - Vec mAttnK; +public: + char unk34[0x40]; }; struct J3DTexMtx { diff --git a/src/JSystem/J3D/J3DGraphBase/J3DMaterial.cpp b/src/JSystem/J3D/J3DGraphBase/J3DMaterial.cpp index 1e454db7..c40f69e8 100644 --- a/src/JSystem/J3D/J3DGraphBase/J3DMaterial.cpp +++ b/src/JSystem/J3D/J3DGraphBase/J3DMaterial.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -8,6 +9,28 @@ #pragma opt_strength_reduction off +void J3DColorBlockLightOff::initialize() +{ + mColorChanNum = 0; + for (u32 i = 0; i < ARRAY_COUNT(mMatColor); ++i) + mMatColor[i] = j3dDefaultColInfo; + for (u32 i = 0; i < ARRAY_COUNT(mColorChan); ++i) + mColorChan[i].mChanCtrl = 0xFFFF; +} + +void J3DColorBlockLightOn::initialize() +{ + mColorChanNum = 0; + for (u32 i = 0; i < ARRAY_COUNT(mMatColor); i++) + mMatColor[i] = j3dDefaultColInfo; + for (u32 i = 0; i < ARRAY_COUNT(mAmbColor); i++) + mAmbColor[i] = j3dDefaultAmbInfo; + for (u32 i = 0; i < ARRAY_COUNT(mColorChan); ++i) + mColorChan[i].mChanCtrl = 0xFFFF; + for (u32 i = 0; i < ARRAY_COUNT(mLight); ++i) + mLight[i] = nullptr; +} + void J3DTevBlock2::initialize() { mTexNo[0] = 0xFFFF; @@ -89,6 +112,9 @@ void J3DTevBlock16::initialize() } } +s32 J3DColorBlockLightOff::countDLSize() { return 0x60; } +s32 J3DColorBlockLightOn::countDLSize() { return 0x140; } + s32 J3DTevBlock1::countDLSize() { return 0x80; } s32 J3DTevBlock2::countDLSize() { return 0x180; } s32 J3DTevBlock4::countDLSize() { return 0x260; } @@ -109,6 +135,45 @@ inline void loadTexCoordScale(GXTexCoordID coord, info.field_0x02, info.field_0x06 == 1, 0); } +// TODO: header +extern void loadCullMode(u8); + +void J3DColorBlockLightOff::load() +{ + for (u32 i = 0; i < ARRAY_COUNT(mMatColor); ++i) + J3DGDSetChanMatColor((GXChannelID)(GX_COLOR0A0 + i), + mMatColor[i].color); + + for (u32 i = 0; i < ARRAY_COUNT(mColorChan); ++i) + mColorChan[i].load(i); + + if (mCullMode != 0xFF) + loadCullMode(mCullMode); +} + +void J3DColorBlockLightOn::load() +{ + for (u32 i = 0; i < ARRAY_COUNT(mMatColor); ++i) + J3DGDSetChanMatColor((GXChannelID)(GX_COLOR0A0 + i), + mMatColor[i].color); + + for (u32 i = 0; i < ARRAY_COUNT(mAmbColor); ++i) + J3DGDSetChanAmbColor((GXChannelID)(GX_COLOR0A0 + i), + mAmbColor[i].color); + + for (u32 i = 0; i < ARRAY_COUNT(mColorChan); ++i) + mColorChan[i].load(i); + + for (u32 i = 0; i < 8; i++) { + if (mLight[i]) { + mLight[i]->load(i); + } + } + + if (mCullMode != 0xFF) + loadCullMode(mCullMode); +} + void J3DTevBlock1::load() { if (mTexNo[0] != 0xffff) { @@ -342,6 +407,43 @@ void J3DPEBlockFull::load() loadDither(mDither); } +void J3DColorBlockLightOff::reset(J3DColorBlock* block) +{ + mColorChanNum = block->getColorChanNum(); + + for (u32 i = 0; i < ARRAY_COUNT(mMatColor); i++) + mMatColor[i] = *block->getMatColor(i); + + for (u32 i = 0; i < ARRAY_COUNT(mColorChan); i++) + mColorChan[i] = *block->getColorChan(i); +} + +void J3DColorBlockLightOn::reset(J3DColorBlock* block) +{ + mColorChanNum = block->getColorChanNum(); + + for (u32 i = 0; i < ARRAY_COUNT(mMatColor); i++) + mMatColor[i] = *block->getMatColor(i); + + for (u32 i = 0; i < ARRAY_COUNT(mColorChan); i++) + mColorChan[i] = *block->getColorChan(i); + + for (u32 i = 0; i < ARRAY_COUNT(mAmbColor); i++) { + if (block->getAmbColor(i)) + mAmbColor[i] = *block->getAmbColor(i); + } + + for (u32 i = 0; i < ARRAY_COUNT(mLight); i++) { + if (block->getLight(i) != NULL) { + if (!mLight[i]) + mLight[i] = new J3DLightObj; + + memcpy(mLight[i], block->getLight(i), sizeof(*mLight[i])); + DCStoreRange(mLight[i], sizeof(*mLight[i])); + } + } +} + void J3DTevBlock1::reset(J3DTevBlock* block) { mTexNo[0] = block->getTexNo(0); diff --git a/src/JSystem/J3D/J3DGraphBase/J3DTevs.cpp b/src/JSystem/J3D/J3DGraphBase/J3DTevs.cpp index afa90ecc..0dfaa584 100644 --- a/src/JSystem/J3D/J3DGraphBase/J3DTevs.cpp +++ b/src/JSystem/J3D/J3DGraphBase/J3DTevs.cpp @@ -285,11 +285,12 @@ void loadTexNo(u32 param_1, const u16& param_2) void J3DLightObj::load(u32 id) const { GXLightID light = (GXLightID)(1 << id); - GDSetLightPos(light, mPos.x, mPos.y, mPos.z); - GDSetLightAttn(light, mAttnA.x, mAttnA.y, mAttnA.z, mAttnK.x, mAttnK.y, - mAttnK.z); + GDSetLightPos(light, mLightPosition.x, mLightPosition.y, mLightPosition.z); + GDSetLightAttn(light, mCosAtten.x, mCosAtten.y, mCosAtten.z, mDistAtten.x, + mDistAtten.y, mDistAtten.z); GDSetLightColor(light, mColor); - GDSetLightDir(light, mDir.x, mDir.y, mDir.z); + GDSetLightDir(light, mLightDirection.x, mLightDirection.y, + mLightDirection.z); } void J3DTexMtx::calc()