summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'src/code')
-rw-r--r--src/code/z_skelanime.c70
-rw-r--r--src/code/z_sub_s.c114
2 files changed, 151 insertions, 33 deletions
diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c
index 7f79bb51c..8ebb2ca67 100644
--- a/src/code/z_skelanime.c
+++ b/src/code/z_skelanime.c
@@ -35,7 +35,7 @@ void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skele
OPEN_DISPS(globalCtx->state.gfxCtx);
Matrix_StatePush();
- limb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]);
+ limb = Lib_SegmentedToVirtual(skeleton[limbIndex]);
limbIndex++;
rot = jointTable[limbIndex];
@@ -94,7 +94,7 @@ void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTa
Matrix_StatePush();
- rootLimb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[0]);
+ rootLimb = Lib_SegmentedToVirtual(skeleton[0]);
pos.x = jointTable[0].x;
pos.y = jointTable[0].y;
pos.z = jointTable[0].z;
@@ -146,7 +146,7 @@ void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** s
Matrix_StatePush();
- limb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]);
+ limb = Lib_SegmentedToVirtual(skeleton[limbIndex]);
limbIndex++;
rot = jointTable[limbIndex];
@@ -203,7 +203,7 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* joi
Gfx* limbDList;
Vec3f pos;
Vec3s rot;
- Mtx* mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount));
+ Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount));
if (skeleton == NULL) {
return;
@@ -214,7 +214,7 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* joi
gSPSegment(POLY_OPA_DISP++, 0x0D, mtx);
Matrix_StatePush();
- rootLimb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[0]);
+ rootLimb = Lib_SegmentedToVirtual(skeleton[0]);
pos.x = jointTable[0].x;
pos.y = jointTable[0].y;
pos.z = jointTable[0].z;
@@ -266,7 +266,7 @@ void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skele
Matrix_StatePush();
- limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]);
+ limb = Lib_SegmentedToVirtual(skeleton[limbIndex]);
limbIndex++;
rot = jointTable[limbIndex];
pos.x = limb->jointPos.x;
@@ -421,7 +421,7 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* joi
Gfx* limbDList;
Vec3f pos;
Vec3s rot;
- Mtx* mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount));
+ Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount));
if (skeleton == NULL) {
return;
@@ -473,9 +473,9 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* joi
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
-void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable,
- OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDrawOpa unkDraw,
- Actor* actor, Mtx** mtx) {
+void SkelAnime_DrawTransformFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable,
+ OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw,
+ TransformLimbDrawOpa transformLimbDraw, Actor* actor, Mtx** mtx) {
StandardLimb* limb;
Gfx* newDList;
Gfx* limbDList;
@@ -486,7 +486,7 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec
Matrix_StatePush();
- limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]);
+ limb = Lib_SegmentedToVirtual(skeleton[limbIndex]);
limbIndex++;
rot = jointTable[limbIndex];
@@ -500,8 +500,8 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec
Matrix_JointPosition(&pos, &rot);
Matrix_StatePush();
- //! @bug Does not check unkDraw is not NULL before calling it.
- unkDraw(globalCtx, limbIndex, actor);
+ transformLimbDraw(globalCtx, limbIndex, actor);
+
if (newDList != NULL) {
Gfx* polyTemp = POLY_OPA_DISP;
@@ -523,23 +523,32 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec
}
if (limb->child != LIMB_DONE) {
- func_80134148(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, unkDraw, actor,
- mtx);
+ SkelAnime_DrawTransformFlexLimbOpa(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw,
+ transformLimbDraw, actor, mtx);
}
Matrix_StatePop();
if (limb->sibling != LIMB_DONE) {
- func_80134148(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, unkDraw, actor,
- mtx);
+ SkelAnime_DrawTransformFlexLimbOpa(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw,
+ postLimbDraw, transformLimbDraw, actor, mtx);
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
-void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount,
- OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDrawOpa unkDraw,
- Actor* actor) {
+/**
+ * Draw all limbs of type `StandardLimb` in a given flexible skeleton to the polyOpa buffer
+ * Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs.
+ * An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up.
+ *
+ * Also makes use of a `TransformLimbDraw`, which transforms limbs based on world coordinates, as opposed to local limb
+ * coordinates.
+ * Note that the `TransformLimbDraw` does not have a NULL check, so must be provided even if empty.
+ */
+void SkelAnime_DrawTransformFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount,
+ OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw,
+ TransformLimbDrawOpa transformLimbDraw, Actor* actor) {
StandardLimb* rootLimb;
s32 pad;
Gfx* newDList;
@@ -554,13 +563,13 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable,
OPEN_DISPS(globalCtx->state.gfxCtx);
- mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount));
+ mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount));
gSPSegment(POLY_OPA_DISP++, 0x0D, mtx);
Matrix_StatePush();
- rootLimb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[0]);
+ rootLimb = Lib_SegmentedToVirtual(skeleton[0]);
pos.x = jointTable[0].x;
pos.y = jointTable[0].y;
@@ -573,8 +582,7 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable,
Matrix_JointPosition(&pos, &rot);
Matrix_StatePush();
- //! @bug Does not check unkDraw is not NULL before calling it.
- unkDraw(globalCtx, 1, actor);
+ transformLimbDraw(globalCtx, 1, actor);
if (newDList != NULL) {
Gfx* polyTemp = POLY_OPA_DISP;
@@ -596,8 +604,8 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable,
}
if (rootLimb->child != LIMB_DONE) {
- func_80134148(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, unkDraw, actor,
- &mtx);
+ SkelAnime_DrawTransformFlexLimbOpa(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw,
+ postLimbDraw, transformLimbDraw, actor, &mtx);
}
Matrix_StatePop();
@@ -655,7 +663,7 @@ Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton
Matrix_StatePush();
- limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]);
+ limb = Lib_SegmentedToVirtual(skeleton[limbIndex]);
limbIndex++;
rot = jointTable[limbIndex];
@@ -711,7 +719,7 @@ Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable
Matrix_StatePush();
- rootLimb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[0]);
+ rootLimb = Lib_SegmentedToVirtual(skeleton[0]);
pos.x = jointTable[0].x;
pos.y = jointTable[0].y;
@@ -758,7 +766,7 @@ Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skel
Matrix_StatePush();
- limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]);
+ limb = Lib_SegmentedToVirtual(skeleton[limbIndex]);
limbIndex++;
rot = jointTable[limbIndex];
@@ -821,7 +829,7 @@ Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointT
return NULL;
}
- mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount));
+ mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount));
gSPSegment(gfx++, 0x0D, mtx);
@@ -994,7 +1002,7 @@ void AnimationContext_SetLoadFrame(GlobalContext* globalCtx, LinkAnimationHeader
AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMATION_LINKANIMETION);
if (entry != NULL) {
- LinkAnimationHeader* linkAnimHeader = (LinkAnimationHeader*)Lib_SegmentedToVirtual(animation);
+ LinkAnimationHeader* linkAnimHeader = Lib_SegmentedToVirtual(animation);
u32 ram = frameTable;
osCreateMesgQueue(&entry->data.load.msgQueue, &entry->data.load.msg, 1);
diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c
index 8f0599b55..764b3525f 100644
--- a/src/code/z_sub_s.c
+++ b/src/code/z_sub_s.c
@@ -36,9 +36,119 @@ EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 unk_1A5) {
return door;
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013A860.s")
+Gfx* SubS_DrawTransformFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable,
+ OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw,
+ TransformLimbDraw transformLimbDraw, Actor* actor, Mtx** mtx, Gfx* gfx) {
+ StandardLimb* limb;
+ Gfx* newDList;
+ Gfx* limbDList;
+ Vec3f pos;
+ Vec3s rot;
+
+ Matrix_StatePush();
+ limb = Lib_SegmentedToVirtual(skeleton[limbIndex]);
+ limbIndex++;
+ rot = jointTable[limbIndex];
+ pos.x = limb->jointPos.x;
+ pos.y = limb->jointPos.y;
+ pos.z = limb->jointPos.z;
+ newDList = limbDList = limb->dList;
+
+ if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &newDList, &pos, &rot, actor, &gfx)) {
+ Matrix_JointPosition(&pos, &rot);
+ Matrix_StatePush();
+
+ transformLimbDraw(globalCtx, limbIndex, actor, &gfx);
+
+ if (newDList != NULL) {
+ Matrix_ToMtx(*mtx);
+ gSPMatrix(gfx++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(gfx++, newDList);
+ (*mtx)++;
+ } else if (limbDList != NULL) {
+ Matrix_ToMtx(*mtx);
+ (*mtx)++;
+ }
+ Matrix_StatePop();
+ }
+ if (postLimbDraw != NULL) {
+ postLimbDraw(globalCtx, limbIndex, &limbDList, &rot, actor, &gfx);
+ }
+ if (limb->child != LIMB_DONE) {
+ gfx = SubS_DrawTransformFlexLimb(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw,
+ transformLimbDraw, actor, mtx, gfx);
+ }
+ Matrix_StatePop();
+ if (limb->sibling != LIMB_DONE) {
+ gfx = SubS_DrawTransformFlexLimb(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw,
+ transformLimbDraw, actor, mtx, gfx);
+ }
+ return gfx;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AB00.s")
+/**
+ * Draw all limbs of type `StandardLimb` in a given flexible skeleton
+ * Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs.
+ * An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up.
+ *
+ * Also makes use of a `TransformLimbDraw`, which transforms limbs based on world coordinates, as opposed to local limb
+ * coordinates.
+ * Note that the `TransformLimbDraw` does not have a NULL check, so must be provided even if empty.
+ */
+Gfx* SubS_DrawTransformFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount,
+ OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw,
+ TransformLimbDraw transformLimbDraw, Actor* actor, Gfx* gfx) {
+ StandardLimb* rootLimb;
+ s32 pad;
+ Gfx* newDlist;
+ Gfx* limbDList;
+ Vec3f pos;
+ Vec3s rot;
+ Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(dListCount * sizeof(Mtx)));
+
+ if (skeleton == NULL) {
+ return NULL;
+ }
+
+ gSPSegment(gfx++, 0x0D, mtx);
+ Matrix_StatePush();
+ rootLimb = Lib_SegmentedToVirtual(skeleton[0]);
+ pos.x = jointTable->x;
+ pos.y = jointTable->y;
+ pos.z = jointTable->z;
+ rot = jointTable[1];
+ newDlist = rootLimb->dList;
+ limbDList = rootLimb->dList;
+
+ if (overrideLimbDraw == NULL || !overrideLimbDraw(globalCtx, 1, &newDlist, &pos, &rot, actor, &gfx)) {
+ Matrix_JointPosition(&pos, &rot);
+ Matrix_StatePush();
+
+ transformLimbDraw(globalCtx, 1, actor, &gfx);
+
+ if (newDlist != NULL) {
+ Matrix_ToMtx(mtx);
+ gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(gfx++, newDlist);
+ mtx++;
+ } else if (limbDList != NULL) {
+ Matrix_ToMtx(mtx);
+ mtx++;
+ }
+ Matrix_StatePop();
+ }
+
+ if (postLimbDraw != NULL) {
+ postLimbDraw(globalCtx, 1, &limbDList, &rot, actor, &gfx);
+ }
+
+ if (rootLimb->child != LIMB_DONE) {
+ gfx = SubS_DrawTransformFlexLimb(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw,
+ postLimbDraw, transformLimbDraw, actor, &mtx, gfx);
+ }
+ Matrix_StatePop();
+ return gfx;
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AD6C.s")