From 317fb95c278b1ac5d74cffa04a6ecc7900aa8f05 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Fri, 27 Feb 2026 01:04:44 +0100 Subject: [PATCH] Make GXVtxDescList and GXVtxAttrFmtList not be behind BE Fixes a stub call because we couldn't pass the BE form to the API --- include/JSystem/J3DGraphBase/J3DShape.h | 4 +- include/JSystem/J3DGraphBase/J3DVertex.h | 4 +- .../JSystem/J3DGraphLoader/J3DShapeFactory.h | 6 +-- include/dusk/endian_gx.hpp | 4 ++ .../J3DGraphAnimator/J3DSkinDeform.cpp | 8 ++-- src/JSystem/J3DGraphBase/J3DShape.cpp | 25 ++++++------ src/JSystem/J3DGraphLoader/J3DModelLoader.cpp | 16 ++++++-- .../J3DGraphLoader/J3DShapeFactory.cpp | 25 +++++++++++- src/dusk/endian.cpp | 38 ++++++++++++++----- 9 files changed, 92 insertions(+), 38 deletions(-) diff --git a/include/JSystem/J3DGraphBase/J3DShape.h b/include/JSystem/J3DGraphBase/J3DShape.h index 37e26f899c..9354bb21c9 100644 --- a/include/JSystem/J3DGraphBase/J3DShape.h +++ b/include/JSystem/J3DGraphBase/J3DShape.h @@ -185,7 +185,7 @@ public: bool getNBTFlag() const { return mHasNBT; } u32 getBumpMtxOffset() const { return mBumpMtxOffset; } void setBumpMtxOffset(u32 offset) { mBumpMtxOffset = offset; } - BE(GXVtxDescList)* getVtxDesc() { return mVtxDesc; } + GXVtxDescList* getVtxDesc() { return mVtxDesc; } J3DMaterial* getMaterial() const { return mMaterial; } u16 getIndex() const { return mIndex; } @@ -213,7 +213,7 @@ private: /* 0x14 */ Vec mMin; /* 0x20 */ Vec mMax; /* 0x2C */ u8* mVcdVatCmd; - /* 0x30 */ BE(GXVtxDescList)* mVtxDesc; + /* 0x30 */ GXVtxDescList* mVtxDesc; /* 0x34 */ bool mHasNBT; /* 0x38 */ J3DShapeMtx** mShapeMtx; /* 0x3C */ J3DShapeDraw** mShapeDraw; diff --git a/include/JSystem/J3DGraphBase/J3DVertex.h b/include/JSystem/J3DGraphBase/J3DVertex.h index 02c15e2499..f52a2f360e 100644 --- a/include/JSystem/J3DGraphBase/J3DVertex.h +++ b/include/JSystem/J3DGraphBase/J3DVertex.h @@ -42,7 +42,7 @@ public: u32 getNrmNum() const { return mNrmNum; } u32 getVtxNum() const { return mVtxNum; } u32 getColNum() const { return mColNum; } - BE(GXVtxAttrFmtList)* getVtxAttrFmtList() const { return mVtxAttrFmtList; } + GXVtxAttrFmtList* getVtxAttrFmtList() const { return mVtxAttrFmtList; } u8 getVtxPosFrac() const { return mVtxPosFrac; } u8 getVtxNrmFrac() const { return mVtxNrmFrac; } int getVtxPosType() const { return mVtxPosType; } @@ -61,7 +61,7 @@ private: /* 0x08 */ u32 mColNum; /* 0x0C */ u32 mTexCoordNum; /* 0x10 */ u32 mPacketNum; - /* 0x14 */ BE(GXVtxAttrFmtList)* mVtxAttrFmtList; + /* 0x14 */ GXVtxAttrFmtList* mVtxAttrFmtList; /* 0x18 */ void* mVtxPosArray; /* 0x1C */ void* mVtxNrmArray; /* 0x20 */ void* mVtxNBTArray; diff --git a/include/JSystem/J3DGraphLoader/J3DShapeFactory.h b/include/JSystem/J3DGraphLoader/J3DShapeFactory.h index 90a9bcb602..cacba467be 100644 --- a/include/JSystem/J3DGraphLoader/J3DShapeFactory.h +++ b/include/JSystem/J3DGraphLoader/J3DShapeFactory.h @@ -49,7 +49,7 @@ struct J3DShapeDrawInitData { */ struct J3DShapeFactory { J3DShapeFactory(J3DShapeBlock const&); - J3DShape* create(int, u32, BE(GXVtxDescList)*); + J3DShape* create(int, u32, GXVtxDescList*); J3DShapeMtx* newShapeMtx(u32, int, int) const; J3DShapeDraw* newShapeDraw(int, int) const; void allocVcdVatCmdBuffer(u32); @@ -59,7 +59,7 @@ struct J3DShapeFactory { /* 0x00 */ J3DShapeInitData* mShapeInitData; /* 0x04 */ BE(u16)* mIndexTable; - /* 0x08 */ BE(GXVtxDescList)* mVtxDescList; + /* 0x08 */ GXVtxDescList* mVtxDescList; /* 0x0C */ BE(u16)* mMtxTable; /* 0x10 */ u8* mDisplayListData; /* 0x14 */ J3DShapeMtxInitData* mMtxInitData; @@ -67,7 +67,7 @@ struct J3DShapeFactory { /* 0x1C */ u8* mVcdVatCmdBuffer; u16 getMtxGroupNum(int no) const { return mShapeInitData[mIndexTable[no]].mMtxGroupNum; } - BE(GXVtxDescList)* getVtxDescList(int no) const { return (BE(GXVtxDescList)*)((u8*)mVtxDescList + mShapeInitData[mIndexTable[no]].mVtxDescListIndex); } + GXVtxDescList* getVtxDescList(int no) const { return (GXVtxDescList*)((u8*)mVtxDescList + mShapeInitData[mIndexTable[no]].mVtxDescListIndex); } f32 getRadius(int no) const { return mShapeInitData[mIndexTable[no]].mRadius; } #if TARGET_PC // Reference return only used for reading, messes with endian handling diff --git a/include/dusk/endian_gx.hpp b/include/dusk/endian_gx.hpp index e0fd9cdcba..1193cf1d7c 100644 --- a/include/dusk/endian_gx.hpp +++ b/include/dusk/endian_gx.hpp @@ -7,6 +7,8 @@ template <> struct BE { BE attr; BE type; + + static GXVtxDescList swap[[nodiscard]](GXVtxDescList val); }; template <> @@ -15,4 +17,6 @@ struct BE { BE cnt; BE type; u8 frac; + + static GXVtxAttrFmtList swap[[nodiscard]](GXVtxAttrFmtList val); }; diff --git a/src/JSystem/J3DGraphAnimator/J3DSkinDeform.cpp b/src/JSystem/J3DGraphAnimator/J3DSkinDeform.cpp index ad73e64745..ff464a3642 100644 --- a/src/JSystem/J3DGraphAnimator/J3DSkinDeform.cpp +++ b/src/JSystem/J3DGraphAnimator/J3DSkinDeform.cpp @@ -239,7 +239,7 @@ int J3DSkinDeform::initMtxIndexArray(J3DModelData* pModelData) { int nrm_num = -1; int tex_num = -1; int r23 = 0; - for (BE(GXVtxDescList)* vtxDesc = pModelData->getShapeNodePointer(i)->getVtxDesc(); vtxDesc->attr != 0xff; vtxDesc++) { + for (GXVtxDescList* vtxDesc = pModelData->getShapeNodePointer(i)->getVtxDesc(); vtxDesc->attr != 0xff; vtxDesc++) { switch (vtxDesc->attr) { case GX_VA_PNMTXIDX: pnmtx_num = r23; @@ -356,7 +356,7 @@ void J3DSkinDeform::changeFastSkinDL(J3DModelData* pModelData) { int vtxSize = 0; J3DShape* pShapeNode = pModelData->getShapeNodePointer(i); - for (BE(GXVtxDescList)* vtxDesc = pShapeNode->getVtxDesc(); vtxDesc->attr != GX_VA_NULL; vtxDesc++) { + for (GXVtxDescList* vtxDesc = pShapeNode->getVtxDesc(); vtxDesc->attr != GX_VA_NULL; vtxDesc++) { if (vtxDesc->attr == GX_VA_PNMTXIDX) { pnmtxIdxOffs = vtxSize; } @@ -402,8 +402,8 @@ void J3DSkinDeform::changeFastSkinDL(J3DModelData* pModelData) { for (u16 i = 0; i < pModelData->getShapeNum(); i++) { J3DShape* shape = pModelData->getShapeNodePointer(i); - BE(GXVtxDescList)* desc = shape->getVtxDesc(); - BE(GXVtxDescList)* descDst = desc; + GXVtxDescList* desc = shape->getVtxDesc(); + GXVtxDescList* descDst = desc; for (; desc->attr != GX_VA_NULL; desc++) { if (desc->attr != GX_VA_PNMTXIDX) { descDst->attr = desc->attr; diff --git a/src/JSystem/J3DGraphBase/J3DShape.cpp b/src/JSystem/J3DGraphBase/J3DShape.cpp index 57882b57eb..1839aa08e3 100644 --- a/src/JSystem/J3DGraphBase/J3DShape.cpp +++ b/src/JSystem/J3DGraphBase/J3DShape.cpp @@ -1,10 +1,13 @@ #include "JSystem/JSystem.h" // IWYU pragma: keep #include "JSystem/J3DGraphBase/J3DShape.h" + +#include + +#include +#include "JSystem/J3DGraphBase/J3DFifo.h" #include "JSystem/J3DGraphBase/J3DPacket.h" #include "JSystem/J3DGraphBase/J3DVertex.h" -#include "JSystem/J3DGraphBase/J3DFifo.h" -#include void J3DGDSetVtxAttrFmtv(_GXVtxFmt, GXVtxAttrFmtList const*, bool); void J3DFifoLoadPosMtxImm(Mtx, u32); @@ -43,7 +46,7 @@ void J3DShape::addTexMtxIndexInDL(GXAttr attr, u32 valueBase) { s32 stride = 0; bool found = false; - for (BE(GXVtxDescList)* vtxDesc = getVtxDesc(); vtxDesc->attr != GX_VA_NULL; vtxDesc++) { + for (GXVtxDescList* vtxDesc = getVtxDesc(); vtxDesc->attr != GX_VA_NULL; vtxDesc++) { if (vtxDesc->attr == GX_VA_PNMTXIDX) pnmtxidxOffs = stride; @@ -69,7 +72,7 @@ void J3DShape::addTexMtxIndexInVcd(GXAttr attr) { s32 attrOffs = -1; s32 stride = 0; - BE(GXVtxDescList)* vtxDesc = getVtxDesc(); + GXVtxDescList* vtxDesc = getVtxDesc(); s32 attrCount = 0; for (; vtxDesc->attr != GX_VA_NULL; vtxDesc++) { @@ -82,11 +85,11 @@ void J3DShape::addTexMtxIndexInVcd(GXAttr attr) { if (attrIdx == -1) return; - BE(GXVtxDescList)* newVtxDesc = new BE(GXVtxDescList)[attrCount + 2]; + GXVtxDescList* newVtxDesc = new GXVtxDescList[attrCount + 2]; bool inserted = false; vtxDesc = getVtxDesc(); - BE(GXVtxDescList)* dst = newVtxDesc; + GXVtxDescList* dst = newVtxDesc; for (; vtxDesc->attr != GX_VA_NULL; vtxDesc++) { if ((attr < vtxDesc->attr) && !inserted) { dst->attr = attr; @@ -154,7 +157,7 @@ bool J3DShape::isSameVcdVatCmd(J3DShape* other) { } void J3DShape::makeVtxArrayCmd() { - BE(GXVtxAttrFmtList)* vtxAttr = mVertexData->getVtxAttrFmtList(); + GXVtxAttrFmtList* vtxAttr = mVertexData->getVtxAttrFmtList(); u8 stride[12]; void* array[12]; @@ -210,7 +213,7 @@ void J3DShape::makeVtxArrayCmd() { } } - BE(GXVtxDescList)* vtxDesc = mVtxDesc; + GXVtxDescList* vtxDesc = mVtxDesc; mHasPNMTXIdx = false; for (; vtxDesc->attr != GX_VA_NULL; vtxDesc++) { if (vtxDesc->attr == GX_VA_NBT && vtxDesc->type != GX_NONE) { @@ -237,11 +240,9 @@ void J3DShape::makeVcdVatCmd() { GDLObj gdl_obj; GDInitGDLObj(&gdl_obj, mVcdVatCmd, kVcdVatDLSize); GDSetCurrent(&gdl_obj); - puts("GDSetVtxDescv is stubbed out due to BE issues"); - // GDSetVtxDescv(mVtxDesc); + GDSetVtxDescv(mVtxDesc); makeVtxArrayCmd(); - puts("J3DGDSetVtxAttrFmtv is stubbed out due to BE issues"); - // J3DGDSetVtxAttrFmtv(GX_VTXFMT0, mVertexData->getVtxAttrFmtList(), mHasNBT); + J3DGDSetVtxAttrFmtv(GX_VTXFMT0, mVertexData->getVtxAttrFmtList(), mHasNBT); GDPadCurr32(); GDFlushCurrToMem(); GDSetCurrent(NULL); diff --git a/src/JSystem/J3DGraphLoader/J3DModelLoader.cpp b/src/JSystem/J3DGraphLoader/J3DModelLoader.cpp index 8ba4352bcc..75f24fc801 100644 --- a/src/JSystem/J3DGraphLoader/J3DModelLoader.cpp +++ b/src/JSystem/J3DGraphLoader/J3DModelLoader.cpp @@ -281,7 +281,7 @@ void J3DModelLoader::readInformation(J3DModelInfoBlock const* i_block, u32 i_fla mpModelData->setHierarchy(JSUConvertOffsetToPtr(i_block, i_block->mpHierarchy)); } -static _GXCompType getFmtType(BE(_GXVtxAttrFmtList)* i_fmtList, _GXAttr i_attr) { +static _GXCompType getFmtType(_GXVtxAttrFmtList* i_fmtList, _GXAttr i_attr) { for (; i_fmtList->attr != GX_VA_NULL; i_fmtList++) { if (i_fmtList->attr == i_attr) { return i_fmtList->type; @@ -294,7 +294,7 @@ void J3DModelLoader::readVertex(J3DVertexBlock const* i_block) { J3D_ASSERT_NULLPTR(577, i_block); J3DVertexData& vertex_data = mpModelData->getVertexData(); vertex_data.mVtxAttrFmtList = - JSUConvertOffsetToPtr(i_block, i_block->mpVtxAttrFmtList); + JSUConvertOffsetToPtr(i_block, i_block->mpVtxAttrFmtList); vertex_data.mVtxPosArray = JSUConvertOffsetToPtr(i_block, i_block->mpVtxPosArray); vertex_data.mVtxNrmArray = JSUConvertOffsetToPtr(i_block, i_block->mpVtxNrmArray); vertex_data.mVtxNBTArray = JSUConvertOffsetToPtr(i_block, i_block->mpVtxNBTArray); @@ -307,6 +307,16 @@ void J3DModelLoader::readVertex(J3DVertexBlock const* i_block) { JSUConvertOffsetToPtr(i_block, i_block->mpVtxTexCoordArray[i]); } +#if TARGET_LITTLE_ENDIAN + for (GXVtxAttrFmtList* attrFmt = vertex_data.mVtxAttrFmtList;; attrFmt++) { + *attrFmt = BE::swap(*attrFmt); + + if (attrFmt->attr == GX_VA_NULL) { + break; + } + } +#endif + u32 nrm_size = 12; if (getFmtType(vertex_data.mVtxAttrFmtList, GX_VA_NRM) == GX_F32) { nrm_size = 12; @@ -517,7 +527,7 @@ void J3DModelLoader::readShape(J3DShapeBlock const* i_block, u32 i_flags) { J3D_ASSERT_ALLOCMEM(1034, shape_table->mShapeNodePointer); factory.allocVcdVatCmdBuffer(shape_table->mShapeNum); J3DModelHierarchy const* hierarchy_entry = mpModelData->getHierarchy(); - BE(GXVtxDescList)* vtx_desc_list = NULL; + GXVtxDescList* vtx_desc_list = NULL; for (; hierarchy_entry->mType != 0; hierarchy_entry++) { if (hierarchy_entry->mType == 0x12) { shape_table->mShapeNodePointer[hierarchy_entry->mValue] = diff --git a/src/JSystem/J3DGraphLoader/J3DShapeFactory.cpp b/src/JSystem/J3DGraphLoader/J3DShapeFactory.cpp index d69c0629cf..8e679daf7a 100644 --- a/src/JSystem/J3DGraphLoader/J3DShapeFactory.cpp +++ b/src/JSystem/J3DGraphLoader/J3DShapeFactory.cpp @@ -7,19 +7,40 @@ #include "JSystem/JSupport/JSupport.h" #include #include "global.h" +#include J3DShapeFactory::J3DShapeFactory(J3DShapeBlock const& block) { mShapeInitData = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpShapeInitData); mIndexTable = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpIndexTable); - mVtxDescList = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpVtxDescList); + mVtxDescList = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpVtxDescList); mMtxTable = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpMtxTable); mDisplayListData = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpDisplayListData); mMtxInitData = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpMtxInitData); mDrawInitData = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpDrawInitData); mVcdVatCmdBuffer = NULL; + +#if TARGET_LITTLE_ENDIAN + // mVtxDescList is in big endian, swap to little endian. + int maxVtxDescListStart = 0; + for (int shapeIdx = 0; shapeIdx < block.mShapeNum; shapeIdx++) { + u16 thisIndex = mShapeInitData[mIndexTable[shapeIdx]].mVtxDescListIndex; + maxVtxDescListStart = std::max( + maxVtxDescListStart, + (int)(thisIndex / sizeof(GXVtxDescList))); + } + + GXVtxDescList* lastEntry = mVtxDescList + maxVtxDescListStart; + while (lastEntry->attr != BE(GXAttr)::swap(GX_VA_NULL)) { + lastEntry++; + } + + for (GXVtxDescList* entry = mVtxDescList; entry <= lastEntry; entry++) { + *entry = BE(GXVtxDescList)::swap(*entry); + } +#endif } -J3DShape* J3DShapeFactory::create(int no, u32 flag, BE(GXVtxDescList)* vtxDesc) { +J3DShape* J3DShapeFactory::create(int no, u32 flag, GXVtxDescList* vtxDesc) { J3DShape* shape = new J3DShape; J3D_ASSERT_ALLOCMEM(67, shape); shape->mMtxGroupNum = getMtxGroupNum(no); diff --git a/src/dusk/endian.cpp b/src/dusk/endian.cpp index 43c422f49f..bdde738911 100644 --- a/src/dusk/endian.cpp +++ b/src/dusk/endian.cpp @@ -1,15 +1,6 @@ #include #include "dusk/endian.h" - -template <> -GXColorS10 BE::swap(GXColorS10 val) { - return { - be16s(val.r), - be16s(val.g), - be16s(val.b), - be16s(val.a), - }; -} +#include "dusk/endian_gx.hpp" #define IMPL_ENUM(type) \ template <> \ @@ -21,3 +12,30 @@ IMPL_ENUM(GXCullMode); IMPL_ENUM(GXAttr); IMPL_ENUM(GXAttrType); IMPL_ENUM(GXCompType); +IMPL_ENUM(GXCompCnt); + +template <> +GXColorS10 BE::swap(GXColorS10 val) { + return { + be16s(val.r), + be16s(val.g), + be16s(val.b), + be16s(val.a), + }; +} + +GXVtxDescList BE::swap(GXVtxDescList val) { + return { + BE::swap(val.attr), + BE::swap(val.type), + }; +} + +GXVtxAttrFmtList BE::swap(GXVtxAttrFmtList val) { + return { + BE::swap(val.attr), + BE::swap(val.cnt), + BE::swap(val.type), + val.frac + }; +}