diff --git a/configure.py b/configure.py index cece7ac49..7c93cdde9 100644 --- a/configure.py +++ b/configure.py @@ -200,6 +200,7 @@ LIBS = [ Object(NonMatching, "JSystem/JFramework/JFWSystem.cpp"), Object(Matching, "JSystem/J3DGraphBase/J3DVertex.cpp"), Object(NonMatching, "JSystem/J3DGraphBase/J3DPacket.cpp"), + Object(NonMatching, "JSystem/J3DGraphBase/J3DShape.cpp"), Object(Matching, "JSystem/J3DGraphBase/J3DDrawBuffer.cpp"), Object(Matching, "JSystem/J3DU/J3DUDL.cpp"), Object(NonMatching, "JSystem/JParticle/JPATexture.cpp"), diff --git a/include/JSystem/J3DGraphBase/J3DPacket.h b/include/JSystem/J3DGraphBase/J3DPacket.h index 278fb9186..143065ab0 100644 --- a/include/JSystem/J3DGraphBase/J3DPacket.h +++ b/include/JSystem/J3DGraphBase/J3DPacket.h @@ -179,9 +179,11 @@ public: void setModel(J3DModel* pModel) { mpModel = pModel; } void setDrawMtx(Mtx** pDrawMtx) { mpDrawMtx = pDrawMtx; } void setNrmMtx(Mtx33** pNrmMtx) { mpNrmMtx = pNrmMtx; } + void setBaseMtxPtr(Mtx* pMtx) { mpBaseMtxPtr = pMtx; } J3DShape* getShape() const { return mpShape; } J3DModel* getModel() const { return mpModel; } + Mtx* getBaseMtxPtr() const { return mpBaseMtxPtr; } public: /* 0x24 */ J3DShape* mpShape; diff --git a/include/JSystem/J3DGraphBase/J3DShape.h b/include/JSystem/J3DGraphBase/J3DShape.h index 457724a86..a1fdf2479 100644 --- a/include/JSystem/J3DGraphBase/J3DShape.h +++ b/include/JSystem/J3DGraphBase/J3DShape.h @@ -121,6 +121,7 @@ public: static void resetVcdVatCache() { sOldVcdVatCmd = NULL; } static void* sOldVcdVatCmd; + static u8 sEnvelopeFlag; private: friend struct J3DShapeFactory; diff --git a/include/JSystem/J3DGraphBase/J3DShapeMtx.h b/include/JSystem/J3DGraphBase/J3DShapeMtx.h index 029e73ece..8c2a29f8a 100644 --- a/include/JSystem/J3DGraphBase/J3DShapeMtx.h +++ b/include/JSystem/J3DGraphBase/J3DShapeMtx.h @@ -54,6 +54,7 @@ public: static u32 sCurrentPipeline; // static J3DScaleFlag sCurrentScaleFlag; static u8* sCurrentScaleFlag; + static u8 sNBTFlag; static u32 sTexMtxLoadType; static void setCurrentPipeline(u32 pipeline) { sCurrentPipeline = pipeline; } diff --git a/include/JSystem/J3DGraphBase/J3DVertex.h b/include/JSystem/J3DGraphBase/J3DVertex.h index ed07b0648..5598f4914 100644 --- a/include/JSystem/J3DGraphBase/J3DVertex.h +++ b/include/JSystem/J3DGraphBase/J3DVertex.h @@ -53,11 +53,11 @@ private: /* 0x1C */ void* mVtxNBTArray; /* 0x20 */ GXColor* mVtxColorArray[2]; /* 0x28 */ void* mVtxTexCoordArray[8]; - /* 0x48 */ u8 mPacketNum; + /* 0x48 */ u8 mVtxPosFrac; /* 0x4C */ GXCompType mVtxPosType; - /* 0x50 */ u8 mVtxPosFrac; + /* 0x50 */ u8 mVtxNrmFrac; /* 0x54 */ GXCompType mVtxNrmType; - /* 0x58 */ u8 mVtxNrmFrac; + /* 0x58 */ u32 mPacketNum; }; class J3DVertexBuffer { diff --git a/src/JSystem/J3DGraphBase/J3DShape.cpp b/src/JSystem/J3DGraphBase/J3DShape.cpp index 666ff9e7a..1dcd464de 100644 --- a/src/JSystem/J3DGraphBase/J3DShape.cpp +++ b/src/JSystem/J3DGraphBase/J3DShape.cpp @@ -4,79 +4,264 @@ // #include "JSystem/J3DGraphBase/J3DShape.h" +#include "JSystem/J3DGraphBase/J3DPacket.h" +#include "JSystem/J3DGraphBase/J3DSys.h" +#include "JSystem/J3DGraphBase/J3DVertex.h" +#include "dolphin/gd/GDBase.h" +#include "dolphin/gd/GDGeometry.h" +#include "dolphin/os/OS.h" #include "dolphin/types.h" +extern void J3DGDSetVtxAttrFmtv(_GXVtxFmt, GXVtxAttrFmtList *, bool); +extern void J3DFifoLoadPosMtxImm(Mtx, u32); +extern void J3DFifoLoadNrmMtxImm(Mtx, u32); + /* 802DD18C-802DD1FC .text initialize__8J3DShapeFv */ + void J3DShape::initialize() { - /* Nonmatching */ + mMaterial = NULL; + mIndex = -1; + mMtxGroupNum = 0; + mFlags = 0; + mRadius = 0.0f; + mMin.x = 0.0f; + mMin.y = 0.0f; + mMin.z = 0.0f; + mMax.x = 0.0f; + mMax.y = 0.0f; + mMax.z = 0.0f; + mVtxDesc = NULL; + mShapeMtx = NULL; + mShapeDraw = NULL; + mVertexData = NULL; + mDrawMtxData = NULL; + mScaleFlagArray = NULL; + mDrawMtx = NULL; + mNrmMtx = NULL; + mCurrentViewNo = &j3dDefaultViewNo; + mHasNBT = false; + mHasPNMTXIdx = false; } /* 802DD1FC-802DD27C .text calcNBTScale__8J3DShapeFRC3VecPA3_A3_fPA3_A3_f */ -void J3DShape::calcNBTScale(const Vec&, float(*)[3][3], float(*)[3][3]) { - /* Nonmatching */ +void J3DShape::calcNBTScale(Vec const& param_0, Mtx33* param_1, Mtx33* param_2) { + for (u16 i = 0; i < getMtxGroupNum(); i++) + getShapeMtx(i)->calcNBTScale(param_0, param_1, param_2); } /* 802DD27C-802DD2F0 .text countBumpMtxNum__8J3DShapeCFv */ -void J3DShape::countBumpMtxNum() const { - /* Nonmatching */ +u32 J3DShape::countBumpMtxNum() const { + u32 num = 0; + for (u16 i = 0; i < getMtxGroupNum(); i++) + num += getShapeMtx(i)->getUseMtxNum(); + return num; } /* 802DD2F0-802DD308 .text J3DLoadCPCmd__FUcUl */ -void J3DLoadCPCmd(unsigned char, unsigned long) { - /* Nonmatching */ +void J3DLoadCPCmd(u8 cmd, u32 param) { + GFX_FIFO(u8) = GX_CMD_LOAD_CP_REG; + GFX_FIFO(u8) = cmd; + GFX_FIFO(u32) = param; } /* 802DD308-802DD344 .text J3DLoadArrayBasePtr__F7_GXAttrPv */ -void J3DLoadArrayBasePtr(_GXAttr, void*) { - /* Nonmatching */ +static void J3DLoadArrayBasePtr(_GXAttr attr, void* data) { + u32 idx = (attr == GX_VA_NBT) ? 1 : (attr - GX_VA_POS); + J3DLoadCPCmd(0xA0 + idx, ((u32)data & 0x7FFFFFFF)); } /* 802DD344-802DD3B4 .text loadVtxArray__8J3DShapeCFv */ void J3DShape::loadVtxArray() const { - /* Nonmatching */ + J3DLoadArrayBasePtr(GX_VA_POS, j3dSys.getVtxPos()); + if (!mHasNBT) { + J3DLoadArrayBasePtr(GX_VA_NRM, j3dSys.getVtxNrm()); + } + J3DLoadArrayBasePtr(GX_VA_CLR0, j3dSys.getVtxCol()); } /* 802DD3B4-802DD3F0 .text isSameVcdVatCmd__8J3DShapeFP8J3DShape */ -void J3DShape::isSameVcdVatCmd(J3DShape*) { - /* Nonmatching */ +bool J3DShape::isSameVcdVatCmd(J3DShape* other) { + u8* a = other->mVcdVatCmd; + u8* b = mVcdVatCmd; + for (u32 i = 0; i < kVcdVatDLSize; i++) + if (a[i] != b[i]) + return false; + return true; } /* 802DD3F0-802DD6B8 .text makeVtxArrayCmd__8J3DShapeFv */ void J3DShape::makeVtxArrayCmd() { - /* Nonmatching */ + GXVtxAttrFmtList* vtxAttr = mVertexData->getVtxAttrFmtList(); + + u8 stride[0x0C]; + void* array[0x0C]; + for (u32 i = 0; i < 0x0C; i++) { + stride[i] = 0; + array[i] = 0; + } + + for (; vtxAttr->mAttrib != GX_VA_NULL; vtxAttr++) { + switch (vtxAttr->mAttrib) { + case GX_VA_POS: { + if (vtxAttr->mCompType == GX_F32) + stride[vtxAttr->mAttrib - GX_VA_POS] = 0x0C; + else + stride[vtxAttr->mAttrib - GX_VA_POS] = 0x06; + array[vtxAttr->mAttrib - GX_VA_POS] = mVertexData->getVtxPosArray(); + mVertexData->setVtxPosFrac(vtxAttr->mCompShift); + mVertexData->setVtxPosType((GXCompType)vtxAttr->mCompType); + } break; + case GX_VA_NRM: { + if (vtxAttr->mCompType == GX_F32) + stride[vtxAttr->mAttrib - GX_VA_POS] = 0x0C; + else + stride[vtxAttr->mAttrib - GX_VA_POS] = 0x06; + array[vtxAttr->mAttrib - GX_VA_POS] = mVertexData->getVtxNrmArray(); + mVertexData->setVtxNrmFrac(vtxAttr->mCompShift); + mVertexData->setVtxNrmType((GXCompType)vtxAttr->mCompType); + } break; + case GX_VA_CLR0: + case GX_VA_CLR1: { + stride[vtxAttr->mAttrib - GX_VA_POS] = 0x04; + array[vtxAttr->mAttrib - GX_VA_POS] = + mVertexData->getVtxColorArray(vtxAttr->mAttrib - GX_VA_CLR0); + } break; + case GX_VA_TEX0: + case GX_VA_TEX1: + case GX_VA_TEX2: + case GX_VA_TEX3: + case GX_VA_TEX4: + case GX_VA_TEX5: + case GX_VA_TEX6: + case GX_VA_TEX7: { + if (vtxAttr->mCompType == GX_F32) + stride[vtxAttr->mAttrib - GX_VA_POS] = 0x08; + else + stride[vtxAttr->mAttrib - GX_VA_POS] = 0x04; + array[vtxAttr->mAttrib - GX_VA_POS] = mVertexData->getVtxTexCoordArray(vtxAttr->mAttrib - GX_VA_TEX0); + } break; + default: + break; + } + } + + GXVtxDescList* vtxDesc = mVtxDesc; + mHasPNMTXIdx = false; + for (; vtxDesc->attr != GX_VA_NULL; vtxDesc++) { + if (vtxDesc->attr == GX_VA_NBT && vtxDesc->type != GX_NONE) { + mHasNBT = true; + stride[GX_VA_NRM - GX_VA_POS] *= 3; + array[GX_VA_NRM - GX_VA_POS] = mVertexData->getVtxNBTArray(); + } else if (vtxDesc->attr == GX_VA_PNMTXIDX && vtxDesc->type != GX_NONE) { + mHasPNMTXIdx = true; + } + } + + for (s32 i = 0; i < 0x0C; i++) { + if (array[i] != 0) + GDSetArray((GXAttr)(i + GX_VA_POS), array[i], stride[i]); + else + GDSetArrayRaw((GXAttr)(i + GX_VA_POS), NULL, stride[i]); + } } /* 802DD6B8-802DD72C .text makeVcdVatCmd__8J3DShapeFv */ void J3DShape::makeVcdVatCmd() { - /* Nonmatching */ + GDLObj gdl_obj; + GDInitGDLObj(&gdl_obj, mVcdVatCmd, kVcdVatDLSize); + GDSetCurrent(&gdl_obj); + GDSetVtxDescv(mVtxDesc); + makeVtxArrayCmd(); + J3DGDSetVtxAttrFmtv(GX_VTXFMT0, mVertexData->getVtxAttrFmtList(), mHasNBT); + GDPadCurr32(); + GDFlushCurrToMem(); + GDSetCurrent(NULL); } +void* J3DShape::sOldVcdVatCmd; + /* 802DD72C-802DD7CC .text loadPreDrawSetting__8J3DShapeCFv */ void J3DShape::loadPreDrawSetting() const { - /* Nonmatching */ + if (sOldVcdVatCmd != mVcdVatCmd) { + GXCallDisplayList(mVcdVatCmd, kVcdVatDLSize); + sOldVcdVatCmd = mVcdVatCmd; + } + + mCurrentMtx.load(); } +u8 J3DShape::sEnvelopeFlag; + /* 802DD7CC-802DD874 .text setArrayAndBindPipeline__8J3DShapeCFv */ void J3DShape::setArrayAndBindPipeline() const { - /* Nonmatching */ + J3DShapeMtx::setCurrentPipeline(getPipeline()); + loadVtxArray(); + j3dSys.setModelDrawMtx(mDrawMtx[*mCurrentViewNo]); + j3dSys.setModelNrmMtx(mNrmMtx[*mCurrentViewNo]); + J3DShapeMtx::sCurrentScaleFlag = mScaleFlagArray; + J3DShapeMtx::sNBTFlag = mHasNBT; + J3DShape::sEnvelopeFlag = mHasPNMTXIdx; } /* 802DD874-802DD9FC .text drawFast__8J3DShapeCFv */ void J3DShape::drawFast() const { - /* Nonmatching */ + if (sOldVcdVatCmd != mVcdVatCmd) { + GXCallDisplayList(mVcdVatCmd, kVcdVatDLSize); + sOldVcdVatCmd = mVcdVatCmd; + } + + if (sEnvelopeFlag != 0 && !mHasPNMTXIdx) + mCurrentMtx.load(); + + setArrayAndBindPipeline(); + if (!checkFlag(J3DShpFlag_NoMtx)) { + for (u16 i = 0; i < getMtxGroupNum(); i++) { + if (getShapeMtx(i) != NULL) + getShapeMtx(i)->load(); + if (getShapeDraw(i) != NULL) + getShapeDraw(i)->draw(); + } + } else { + J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), GX_PNMTX0); + J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), GX_PNMTX0); + for (u16 i = 0; i < getMtxGroupNum(); i++) + if (getShapeDraw(i) != NULL) + getShapeDraw(i)->draw(); + } } /* 802DD9FC-802DDA44 .text draw__8J3DShapeCFv */ void J3DShape::draw() const { - /* Nonmatching */ + sOldVcdVatCmd = NULL; + loadPreDrawSetting(); + drawFast(); } /* 802DDA44-802DDAC8 .text simpleDraw__8J3DShapeCFv */ void J3DShape::simpleDraw() const { - /* Nonmatching */ + resetVcdVatCache(); + loadPreDrawSetting(); + J3DShapeMtx::setCurrentPipeline(getPipeline()); + loadVtxArray(); + for (u16 i = 0; i < getMtxGroupNum(); i++) { + if (getShapeDraw(i) != NULL) { + getShapeDraw(i)->draw(); + } + } } /* 802DDAC8-802DDBC4 .text simpleDrawCache__8J3DShapeCFv */ void J3DShape::simpleDrawCache() const { - /* Nonmatching */ + if (sOldVcdVatCmd != mVcdVatCmd) { + GXCallDisplayList(mVcdVatCmd, kVcdVatDLSize); + sOldVcdVatCmd = mVcdVatCmd; + } + + if (sEnvelopeFlag != 0 && !mHasPNMTXIdx) + mCurrentMtx.load(); + + loadVtxArray(); + for (u16 i = 0; i < getMtxGroupNum(); i++) + if (getShapeDraw(i) != NULL) + getShapeDraw(i)->draw(); } diff --git a/src/JSystem/J3DGraphBase/J3DVertex.cpp b/src/JSystem/J3DGraphBase/J3DVertex.cpp index 4ce6b1bb0..306f895a2 100644 --- a/src/JSystem/J3DGraphBase/J3DVertex.cpp +++ b/src/JSystem/J3DGraphBase/J3DVertex.cpp @@ -26,9 +26,9 @@ J3DVertexData::J3DVertexData() { for (int i = 0; i < ARRAY_SIZE(mVtxTexCoordArray); i++) mVtxTexCoordArray[i] = NULL; - mPacketNum = 0; - mVtxPosType = GX_F32; mVtxPosFrac = 0; + mVtxPosType = GX_F32; + mVtxNrmFrac = 0; mVtxNrmType = GX_F32; }