From 9b08f337a55906eac28e404c068336b701a4d0e5 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Mon, 2 Mar 2026 19:53:45 +0100 Subject: [PATCH 1/3] BE support --- include/dusk/endian.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/dusk/endian.h b/include/dusk/endian.h index 03a6665545..58e9bd31ab 100644 --- a/include/dusk/endian.h +++ b/include/dusk/endian.h @@ -160,6 +160,15 @@ inline f32 BE::swap(f32 val) { return RES_F32(val); } +template<> +inline S16Vec BE::swap(S16Vec val) { + return { + BE::swap(val.x), + BE::swap(val.y), + BE::swap(val.z), + }; +} + template<> struct BE { BE x; From d33233c31ba2aeab5b0dd8bdaffba5206e24690c Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Mon, 2 Mar 2026 20:00:46 +0100 Subject: [PATCH 2/3] Animation/joint loading BE fixes --- .../JSystem/J3DGraphAnimator/J3DAnimation.h | 18 +++++---- libs/JSystem/src/J2DGraph/J2DAnmLoader.cpp | 37 ++++++++++++++---- .../src/J3DGraphLoader/J3DAnmLoader.cpp | 38 +++++++++++++++---- .../src/J3DGraphLoader/J3DJointFactory.cpp | 16 ++++++++ 4 files changed, 86 insertions(+), 23 deletions(-) diff --git a/libs/JSystem/include/JSystem/J3DGraphAnimator/J3DAnimation.h b/libs/JSystem/include/JSystem/J3DGraphAnimator/J3DAnimation.h index 7ba48add3f..84f8625a84 100644 --- a/libs/JSystem/include/JSystem/J3DGraphAnimator/J3DAnimation.h +++ b/libs/JSystem/include/JSystem/J3DGraphAnimator/J3DAnimation.h @@ -424,15 +424,17 @@ struct J3DAnmClusterKeyTable { */ struct J3DAnmTransformKeyData { /* 0x00 */ JUTDataBlockHeader mHeader; - /* 0x08 */ u8 field_0x8; - /* 0x09 */ u8 field_0x9; + /* 0x08 */ u8 mLoopMode; + /* 0x09 */ u8 mRotationDecimal; /* 0x0A */ BE(s16) mFrameMax; - /* 0x0C */ BE(u16) field_0xc; - /* 0x10 */ int field_0x10; - /* 0x14 */ OFFSET_PTR mTableOffset; - /* 0x18 */ OFFSET_PTR field_0x18; - /* 0x1c */ OFFSET_PTR field_0x1c; - /* 0x20 */ OFFSET_PTR field_0x20; + /* 0x0C */ BE(u16) mJointAnimationTableCount; + /* 0x0E */ BE(u16) mSCount; + /* 0x10 */ BE(u16) mRCount; + /* 0x12 */ BE(u16) mTCount; + /* 0x14 */ OFFSET_PTR mJointAnimationTableOffs; + /* 0x18 */ OFFSET_PTR mSTableOffs; + /* 0x1c */ OFFSET_PTR mRTableOffs; + /* 0x20 */ OFFSET_PTR mTTableOffs; }; /** diff --git a/libs/JSystem/src/J2DGraph/J2DAnmLoader.cpp b/libs/JSystem/src/J2DGraph/J2DAnmLoader.cpp index da177cd854..176f4e24ec 100644 --- a/libs/JSystem/src/J2DGraph/J2DAnmLoader.cpp +++ b/libs/JSystem/src/J2DGraph/J2DAnmLoader.cpp @@ -175,21 +175,44 @@ void J2DAnmKeyLoader_v15::readAnmTransform(J3DAnmTransformKeyData const* p_data) setAnmTransform(p_anm, p_data); } +#if TARGET_LITTLE_ENDIAN +static void ByteSwapTransformKeyData( + J2DAnmTransformKey& target, + const J3DAnmTransformKeyData& source) { + + for (int i = 0; i < source.mSCount; i += 1) { + be_swap(target.mScaleValues[i]); + } + + for (int i = 0; i < source.mRCount; i += 1) { + be_swap(target.mRotationValues[i]); + } + + for (int i = 0; i < source.mTCount; i += 1) { + be_swap(target.mTranslateValues[i]); + } +} +#endif + void J2DAnmKeyLoader_v15::setAnmTransform(J2DAnmTransformKey* p_anm, J3DAnmTransformKeyData const* p_data) { J3D_PANIC(439, p_anm, "Error : null pointer."); J3D_PANIC(440, p_data, "Error : null pointer."); - p_anm->field_0x22 = p_data->field_0xc; + p_anm->field_0x22 = p_data->mJointAnimationTableCount; p_anm->mFrameMax = p_data->mFrameMax; - p_anm->field_0x4 = p_data->field_0x8; - p_anm->field_0x24 = p_data->field_0x9; + p_anm->field_0x4 = p_data->mLoopMode; + p_anm->field_0x24 = p_data->mRotationDecimal; p_anm->mFrame = 0; p_anm->mInfoTable = - JSUConvertOffsetToPtr(p_data, p_data->mTableOffset); - p_anm->mScaleValues = JSUConvertOffsetToPtr(p_data, p_data->field_0x18); - p_anm->mRotationValues = JSUConvertOffsetToPtr(p_data, p_data->field_0x1c); + JSUConvertOffsetToPtr(p_data, p_data->mJointAnimationTableOffs); + p_anm->mScaleValues = JSUConvertOffsetToPtr(p_data, p_data->mSTableOffs); + p_anm->mRotationValues = JSUConvertOffsetToPtr(p_data, p_data->mRTableOffs); p_anm->mTranslateValues = - JSUConvertOffsetToPtr(p_data, p_data->field_0x20); + JSUConvertOffsetToPtr(p_data, p_data->mTTableOffs); + +#if TARGET_LITTLE_ENDIAN + ByteSwapTransformKeyData(*p_anm, *p_data); +#endif } void J2DAnmKeyLoader_v15::readAnmTextureSRT(J3DAnmTextureSRTKeyData const* p_data) { diff --git a/libs/JSystem/src/J3DGraphLoader/J3DAnmLoader.cpp b/libs/JSystem/src/J3DGraphLoader/J3DAnmLoader.cpp index b3772ea422..4576815eb7 100644 --- a/libs/JSystem/src/J3DGraphLoader/J3DAnmLoader.cpp +++ b/libs/JSystem/src/J3DGraphLoader/J3DAnmLoader.cpp @@ -476,22 +476,44 @@ void J3DAnmKeyLoader_v15::readAnmTransform(const J3DAnmTransformKeyData* param_1 setAnmTransform(anm, param_1); } +#if TARGET_LITTLE_ENDIAN +static void ByteSwapTransformKeyData( + J3DAnmTransformKey& target, + const J3DAnmTransformKeyData& source) { + + for (int i = 0; i < source.mSCount; i += 1) { + be_swap(target.mScaleData[i]); + } + + for (int i = 0; i < source.mRCount; i += 1) { + be_swap(target.mRotData[i]); + } + + for (int i = 0; i < source.mTCount; i += 1) { + be_swap(target.mTransData[i]); + } +} +#endif + void J3DAnmKeyLoader_v15::setAnmTransform(J3DAnmTransformKey* param_1, const J3DAnmTransformKeyData* param_2) { J3D_ASSERT_NULLPTR(944, param_1); J3D_ASSERT_NULLPTR(945, param_2); - param_1->field_0x1e = param_2->field_0xc; + param_1->field_0x1e = param_2->mJointAnimationTableCount; param_1->mFrameMax = param_2->mFrameMax; - param_1->mAttribute = param_2->field_0x8; - param_1->mDecShift = param_2->field_0x9; + param_1->mAttribute = param_2->mLoopMode; + param_1->mDecShift = param_2->mRotationDecimal; param_1->mFrame = 0.0f; param_1->mAnmTable = - JSUConvertOffsetToPtr(param_2, param_2->mTableOffset); - param_1->mScaleData = JSUConvertOffsetToPtr(param_2, param_2->field_0x18); - param_1->mRotData = JSUConvertOffsetToPtr(param_2, param_2->field_0x1c); - param_1->mTransData = JSUConvertOffsetToPtr(param_2, param_2->field_0x20); -} + JSUConvertOffsetToPtr(param_2, param_2->mJointAnimationTableOffs); + param_1->mScaleData = JSUConvertOffsetToPtr(param_2, param_2->mSTableOffs); + param_1->mRotData = JSUConvertOffsetToPtr(param_2, param_2->mRTableOffs); + param_1->mTransData = JSUConvertOffsetToPtr(param_2, param_2->mTTableOffs); +#if TARGET_LITTLE_ENDIAN + ByteSwapTransformKeyData(*param_1, *param_2); +#endif +} void J3DAnmKeyLoader_v15::readAnmTextureSRT(const J3DAnmTextureSRTKeyData* param_1) { J3DAnmTextureSRTKey* anm = (J3DAnmTextureSRTKey*)mAnm; diff --git a/libs/JSystem/src/J3DGraphLoader/J3DJointFactory.cpp b/libs/JSystem/src/J3DGraphLoader/J3DJointFactory.cpp index dafc4ce417..c385b400e1 100644 --- a/libs/JSystem/src/J3DGraphLoader/J3DJointFactory.cpp +++ b/libs/JSystem/src/J3DGraphLoader/J3DJointFactory.cpp @@ -8,6 +8,22 @@ J3DJointFactory::J3DJointFactory(J3DJointBlock const& block) { mJointInitData = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpJointInitData); mIndexTable = JSUConvertOffsetToPtr(&block, (uintptr_t)block.mpIndexTable); + +#if TARGET_LITTLE_ENDIAN + for (int i = 0; i < block.mJointNum; i++) { + auto& index = mIndexTable[i]; + be_swap(index); + + auto initData = &mJointInitData[index]; + be_swap(initData->mKind); + be_swap(initData->mTransformInfo.mScale); + be_swap(initData->mTransformInfo.mRotation); + be_swap(initData->mTransformInfo.mTranslate); + be_swap(initData->mRadius); + be_swap(initData->mMin); + be_swap(initData->mMax); + } +#endif } J3DJoint* J3DJointFactory::create(int no) { From 8a29cb06a354b514e3fc674650e0c8251ad275b8 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Mon, 2 Mar 2026 20:00:55 +0100 Subject: [PATCH 3/3] Fix hardcoded pointer sizes in JPAResource --- libs/JSystem/src/JParticle/JPAResource.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libs/JSystem/src/JParticle/JPAResource.cpp b/libs/JSystem/src/JParticle/JPAResource.cpp index 56c8eec317..ee4658998c 100644 --- a/libs/JSystem/src/JParticle/JPAResource.cpp +++ b/libs/JSystem/src/JParticle/JPAResource.cpp @@ -102,7 +102,10 @@ void JPAResource::init(JKRHeap* heap) { if (mpCalcEmitterFuncListNum != 0) { mpCalcEmitterFuncList = - (EmitterFunc*)JKRAllocFromHeap(heap, mpCalcEmitterFuncListNum * 4, 4); + (EmitterFunc*)JKRAllocFromHeap( + heap, + mpCalcEmitterFuncListNum * sizeof(EmitterFunc), + alignof(EmitterFunc)); } func_no = 0; @@ -200,7 +203,7 @@ void JPAResource::init(JKRHeap* heap) { if (mpCalcParticleFuncListNum != 0) { mpCalcParticleFuncList = - (ParticleFunc*)JKRAllocFromHeap(heap, mpCalcParticleFuncListNum * 4, 4); + (ParticleFunc*)JKRAllocFromHeap(heap, mpCalcParticleFuncListNum * sizeof(ParticleFunc), alignof(ParticleFunc)); } func_no = 0; @@ -320,7 +323,7 @@ void JPAResource::init(JKRHeap* heap) { if (mpCalcParticleChildFuncListNum != 0) { mpCalcParticleChildFuncList = - (ParticleFunc*)JKRAllocFromHeap(heap, mpCalcParticleChildFuncListNum * 4, 4); + (ParticleFunc*)JKRAllocFromHeap(heap, mpCalcParticleChildFuncListNum * sizeof(ParticleFunc), alignof(ParticleFunc)); } func_no = 0; @@ -365,7 +368,7 @@ void JPAResource::init(JKRHeap* heap) { if (mpDrawEmitterFuncListNum != 0) { mpDrawEmitterFuncList = - (EmitterFunc*)JKRAllocFromHeap(heap, mpDrawEmitterFuncListNum * 4, 4); + (EmitterFunc*)JKRAllocFromHeap(heap, mpDrawEmitterFuncListNum * sizeof(EmitterFunc), alignof(EmitterFunc)); } func_no = 0; @@ -468,7 +471,7 @@ void JPAResource::init(JKRHeap* heap) { if (mpDrawEmitterChildFuncListNum != 0) { mpDrawEmitterChildFuncList = - (EmitterFunc*)JKRAllocFromHeap(heap, mpDrawEmitterChildFuncListNum * 4, 4); + (EmitterFunc*)JKRAllocFromHeap(heap, mpDrawEmitterChildFuncListNum * sizeof(EmitterFunc), alignof(EmitterFunc)); } func_no = 0; @@ -518,7 +521,7 @@ void JPAResource::init(JKRHeap* heap) { if (mpDrawParticleFuncListNum != 0) { mpDrawParticleFuncList = - (ParticleFunc*)JKRAllocFromHeap(heap, mpDrawParticleFuncListNum * 4, 4); + (ParticleFunc*)JKRAllocFromHeap(heap, mpDrawParticleFuncListNum * sizeof(ParticleFunc), alignof(ParticleFunc)); } func_no = 0; @@ -628,7 +631,7 @@ void JPAResource::init(JKRHeap* heap) { if (mpDrawParticleChildFuncListNum != 0) { mpDrawParticleChildFuncList = - (ParticleFunc*)JKRAllocFromHeap(heap, mpDrawParticleChildFuncListNum * 4, 4); + (ParticleFunc*)JKRAllocFromHeap(heap, mpDrawParticleChildFuncListNum * sizeof(ParticleFunc), sizeof(EmitterFunc)); } func_no = 0;