diff --git a/decompiler/config/jak1/all-types.gc b/decompiler/config/jak1/all-types.gc index 724e1a5554..f5adbf4ea5 100644 --- a/decompiler/config/jak1/all-types.gc +++ b/decompiler/config/jak1/all-types.gc @@ -11029,7 +11029,7 @@ intended for uncompressed animation objects." (root-channel (inline-array joint-control-channel) :offset 16) (blend-index int32 :offset-assert 20) (active-channels int32 :offset-assert 24) - (generate-frame-function (function (inline-array vector) int process-drawable int) :offset-assert 28) + (generate-frame-function (function joint-anim-frame int process-drawable none) :offset-assert 28) (prebind-function (function pointer int process-drawable none) :offset-assert 32) (postbind-function (function process-drawable none) :offset-assert 36) (effect effect-control :offset-assert 40) @@ -19651,7 +19651,7 @@ to matrix-bits in the compressed header." (define-extern create-interpolated-joint-animation-frame "Generate a drawable's blended joint-animation frame. The GOAL decompressor is normally used; the original scratchpad decompressor remains available through the development switch." - (function (inline-array vector) int process-drawable int)) + (function joint-anim-frame int process-drawable none)) (define-extern mem-size "Collect value's memory categories using flags, optionally print the complete category table, and return the sum of aligned total bytes." diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 439bef38e9..9bba413557 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -166,7 +166,6 @@ set(RUNTIME_SOURCE mips2c/jak1_functions/generic_effect2.cpp mips2c/jak1_functions/generic_merc.cpp mips2c/jak1_functions/generic_tie.cpp - mips2c/jak1_functions/joint.cpp mips2c/jak1_functions/merc_blend_shape.cpp mips2c/jak1_functions/ocean_vu0.cpp mips2c/jak1_functions/ocean.cpp diff --git a/game/mips2c/jak1_functions/joint.cpp b/game/mips2c/jak1_functions/joint.cpp deleted file mode 100644 index 59881d5b7b..0000000000 --- a/game/mips2c/jak1_functions/joint.cpp +++ /dev/null @@ -1,2543 +0,0 @@ -//--------------------------MIPS2C--------------------- -#include "game/kernel/jak1/kscheme.h" -#include "game/mips2c/mips2c_private.h" -using namespace jak1; -// clang-format off - -namespace { -struct Cache { - void* clear_frame_accumulator; // clear-frame-accumulator - void* decompress_fixed_data_to_accumulator; // decompress-fixed-data-to-accumulator - void* decompress_frame_data_pair_to_accumulator; // decompress-frame-data-pair-to-accumulator - void* decompress_frame_data_to_accumulator; // decompress-frame-data-to-accumulator - void* normalize_frame_quaternions; // normalize-frame-quaternions - void* fake_scratchpad_data; // *fake-scratchpad-data* - -} cache; -} - -namespace Mips2C::jak1 { -namespace decompress_frame_data_pair_to_accumulator { -u64 execute(void* ctxt) { - auto* c = (ExecutionContext*)ctxt; - bool bc = false; - u32 next_block = 0; - while(true) { - switch(next_block) { - - case 0: - next_block = 1; - c->daddiu(sp, sp, -64); // daddiu sp, sp, -64 - c->sq(a0, 0, sp); // sq a0, 0(sp) - c->sq(t7, 16, sp); // sq t7, 16(sp) - c->sq(s0, 32, sp); // sq s0, 32(sp) - c->sq(s1, 48, sp); // sq s1, 48(sp) - c->mov128_vf_gpr(vf11, t0); // qmtc2.i vf11, t0 - c->daddu(a3, a3, a1); // daddu a3, a3, a1 - c->mov128_vf_gpr(vf13, a2); // qmtc2.i vf13, a2 - //c->lui(t2, 28672); // lui t2, 28672 - get_fake_spad_addr(t2, cache.fake_scratchpad_data, 0, c); - c->lw(t4, 0, a1); // lw t4, 0(a1) - c->daddiu(v1, a1, 16); // daddiu v1, a1, 16 - c->lw(t5, 4, a1); // lw t5, 4(a1) - c->daddu(s5, t1, r0); // daddu s5, t1, r0 - c->lw(t6, 8, a1); // lw t6, 8(a1) - c->daddu(t4, t4, v1); // daddu t4, t4, v1 - c->vsub_bc(DEST::w, BC::x, vf11, vf0, vf11); // vsubx.w vf11, vf0, vf11 - c->lw(t7, 0, a3); // lw t7, 0(a3) - c->vmul_bc(DEST::xyzw, BC::x, vf13, vf14, vf13); // vmulx.xyzw vf13, vf14, vf13 - c->daddiu(t2, t2, 1760); // daddiu t2, t2, 1760 - c->lw(s2, 56, t1); // lw s2, 56(t1) - c->daddu(t5, t5, v1); // daddu t5, t5, v1 - c->lw(s4, 60, t1); // lw s4, 60(t1) - c->daddu(t6, t6, v1); // daddu t6, t6, v1 - c->addiu(s3, r0, 8); // addiu s3, r0, 8 - c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 - c->vmul_bc(DEST::xy, BC::w, vf13, vf13, vf11); // vmulw.xy vf13, vf13, vf11 - c->lw(s0, 4, a3); // lw s0, 4(a3) - c->vmul_bc(DEST::zw, BC::x, vf13, vf13, vf11); // vmulx.zw vf13, vf13, vf11 - c->lw(s1, 8, a3); // lw s1, 8(a3) - // nop // sll r0, r0, 0 - c->daddiu(v1, a3, 16); // daddiu v1, a3, 16 - c->daddu(t7, t7, v1); // daddu t7, t7, v1 - c->daddu(s0, s0, v1); // daddu s0, s0, v1 - c->daddu(s1, s1, v1); // daddu s1, s1, v1 - // nop // sll r0, r0, 0 - c->andi(t3, s4, 1); // andi t3, s4, 1 - // nop // sll r0, r0, 0 - bc = c->sgpr64(t3) == 0; // beq t3, r0, L10 - // nop // sll r0, r0, 0 - if (bc) {next_block = 2;} // branch non-likely - - break; - - case 1: - next_block = 2; - c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) - c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) - c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) - c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) - c->lqc2(vf5, 0, t7); // lqc2 vf5, 0(t7) - c->lqc2(vf6, 16, t7); // lqc2 vf6, 16(t7) - c->lqc2(vf7, 32, t7); // lqc2 vf7, 32(t7) - c->lqc2(vf8, 48, t7); // lqc2 vf8, 48(t7) - c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) - c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 - c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) - c->daddiu(t7, t7, 64); // daddiu t7, t7, 64 - c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) - c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf5, vf13); // vmaddw.xyzw vf9, vf5, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf2, vf13); // vmaddax.xyzw acc, vf2, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf10, vf6, vf13); // vmaddw.xyzw vf10, vf6, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf3, vf13); // vmaddax.xyzw acc, vf3, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf11, vf7, vf13); // vmaddw.xyzw vf11, vf7, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf4, vf13); // vmaddax.xyzw acc, vf4, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf12, vf8, vf13); // vmaddw.xyzw vf12, vf8, vf13 - c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) - c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) - c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) - c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) - - case 2: - next_block = 3; - c->andi(t3, s4, 2); // andi t3, s4, 2 - c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 - bc = c->sgpr64(t3) == 0; // beq t3, r0, L11 - // nop // sll r0, r0, 0 - if (bc) {next_block = 4;} // branch non-likely - - break; - - case 3: - next_block = 4; - c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) - c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) - c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) - c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) - c->lqc2(vf5, 0, t7); // lqc2 vf5, 0(t7) - c->lqc2(vf6, 16, t7); // lqc2 vf6, 16(t7) - c->lqc2(vf7, 32, t7); // lqc2 vf7, 32(t7) - c->lqc2(vf8, 48, t7); // lqc2 vf8, 48(t7) - c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) - c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 - c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) - c->daddiu(t7, t7, 64); // daddiu t7, t7, 64 - c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) - c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf5, vf13); // vmaddw.xyzw vf9, vf5, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf2, vf13); // vmaddax.xyzw acc, vf2, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf10, vf6, vf13); // vmaddw.xyzw vf10, vf6, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf3, vf13); // vmaddax.xyzw acc, vf3, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf11, vf7, vf13); // vmaddw.xyzw vf11, vf7, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf4, vf13); // vmaddax.xyzw acc, vf4, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf12, vf8, vf13); // vmaddw.xyzw vf12, vf8, vf13 - c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) - c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) - c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) - c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) - - case 4: - next_block = 5; - c->lw(s4, -4, s5); // lw s4, -4(s5) - c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 - - case 5: - next_block = 6; - c->andi(t3, s4, 15); // andi t3, s4, 15 - c->sra(s4, s4, 4); // sra s4, s4, 4 - c->sll(t3, t3, 2); // sll t3, t3, 2 - c->daddiu(s3, s3, -1); // daddiu s3, s3, -1 - c->daddu(t3, t3, t2); // daddu t3, t3, t2 - c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 - c->lw(t3, 0, t3); // lw t3, 0(t3) - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - next_block = 0x4d7666d9 ^ c->gprs[t3].du32[0]; // jr t3 - ASSERT(next_block < 33); - break; - // nop // sll r0, r0, 0 - - case 6: - next_block = 7; - bc = c->sgpr64(s2) == 0; // beq s2, r0, L20 - c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 - if (bc) {next_block = 32;} // branch non-likely - - break; - - case 7: - next_block = 8; - bc = c->sgpr64(s3) != 0; // bne s3, r0, L12 - // nop // sll r0, r0, 0 - if (bc) {next_block = 5;} // branch non-likely - - break; - - case 8: - next_block = 9; - c->lw(s4, 0, s5); // lw s4, 0(s5) - c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 - //beq r0, r0, L12 // beq r0, r0, L12 - c->addiu(s3, r0, 8); // addiu s3, r0, 8 - next_block = 5; // branch always - - break; - - case 9: - next_block = 10; - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(s6, 0, s0); // lw s6, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(gp, 0, s1); // lh gp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->vitof0(DEST::xyzw, vf2, vf2); // vitof0.xyzw vf2, vf2 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf13); // vmadday.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::z, vf3, vf2, vf13); // vmaddz.xyzw vf3, vf2, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 10: - next_block = 11; - c->ld(s6, 0, t4); // ld s6, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->ld(s6, 0, t7); // ld s6, 0(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->lw(gp, 0, s0); // lw gp, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf3, vf2, vf13); // vmaddw.xyzw vf3, vf2, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 11: - next_block = 12; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(t9, 0, t7); // ld t9, 0(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 - c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L14 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 13; - break; - } - - case 13: - next_block = 14; - c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 14: - next_block = 15; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(t9, 0, t7); // ld t9, 0(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->lw(s6, 0, s0); // lw s6, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(gp, 0, s1); // lh gp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L15 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 16; - break; - } - - case 16: - next_block = 17; - c->vitof0(DEST::xyzw, vf2, vf2); // vitof0.xyzw vf2, vf2 - c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf13); // vmadday.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::z, vf3, vf2, vf13); // vmaddz.xyzw vf3, vf2, vf13 - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 17: - next_block = 18; - c->ld(t9, 8, t4); // ld t9, 8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(t9, 8, t7); // ld t9, 8(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->ld(s6, -8, t4); // ld s6, -8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->ld(s6, -8, t7); // ld s6, -8(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->lw(gp, 0, s0); // lw gp, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L16 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 19; - break; - } - - case 19: - next_block = 20; - c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf3, vf2, vf13); // vmaddw.xyzw vf3, vf2, vf13 - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 20: - next_block = 21; - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->lw(t8, 0, s0); // lw t8, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(fp, 0, s1); // lh fp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 21: - next_block = 22; - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(s6, 0, s0); // lw s6, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(gp, 0, s1); // lh gp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->vitof0(DEST::xyzw, vf2, vf2); // vitof0.xyzw vf2, vf2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf13); // vmadday.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::z, vf3, vf2, vf13); // vmaddz.xyzw vf3, vf2, vf13 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->lw(t8, 0, s0); // lw t8, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(fp, 0, s1); // lh fp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 22: - next_block = 23; - c->ld(s6, 0, t4); // ld s6, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->ld(s6, 0, t7); // ld s6, 0(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->lw(gp, 0, s0); // lw gp, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf3, vf2, vf13); // vmaddw.xyzw vf3, vf2, vf13 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->lw(t8, 0, s0); // lw t8, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(fp, 0, s1); // lh fp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 23: - next_block = 24; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(t9, 0, t7); // ld t9, 0(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->lw(t8, 0, s0); // lw t8, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(fp, 0, s1); // lh fp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L17 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 25; - break; - } - - case 25: - next_block = 26; - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 - c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 26: - next_block = 27; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(t9, 0, t7); // ld t9, 0(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->lw(s6, 0, s0); // lw s6, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(gp, 0, s1); // lh gp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L18 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 28; - break; - } - - case 28: - next_block = 29; - c->vitof0(DEST::xyzw, vf2, vf2); // vitof0.xyzw vf2, vf2 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf13); // vmadday.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::z, vf3, vf2, vf13); // vmaddz.xyzw vf3, vf2, vf13 - c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->lw(t8, 0, s0); // lw t8, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(fp, 0, s1); // lh fp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 29: - next_block = 30; - c->ld(t9, 8, t4); // ld t9, 8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(t9, 8, t7); // ld t9, 8(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf5, t9); // qmtc2.i vf5, t9 - c->ld(s6, -8, t4); // ld s6, -8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->vitof15(DEST::xyzw, vf5, vf5); // vitof15.xyzw vf5, vf5 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->vmula_bc(DEST::xyzw, BC::x, vf4, vf13); // vmulax.xyzw acc, vf4, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf4, vf5, vf13); // vmaddw.xyzw vf4, vf5, vf13 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->ld(s6, -8, t7); // ld s6, -8(t7) - c->daddiu(t7, t7, 8); // daddiu t7, t7, 8 - c->lw(gp, 0, s0); // lw gp, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->mov128_vf_gpr(vf2, s6); // qmtc2.i vf2, s6 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L19 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 31; - break; - } - - case 31: - next_block = 32; - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf1, vf13); // vmaddax.xyzw acc, vf1, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf3, vf2, vf13); // vmaddw.xyzw vf3, vf2, vf13 - c->vadd(DEST::xyzw, vf6, vf6, vf4); // vadd.xyzw vf6, vf6, vf4 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->lw(t8, 0, s0); // lw t8, 0(s0) - c->daddiu(s0, s0, 4); // daddiu s0, s0, 4 - c->lh(fp, 0, s1); // lh fp, 0(s1) - c->daddiu(s1, s1, 2); // daddiu s1, s1, 2 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf8, t8); // qmtc2.i vf8, t8 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vitof12(DEST::xyzw, vf8, vf8); // vitof12.xyzw vf8, vf8 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadda_bc(DEST::xyzw, BC::x, vf7, vf13); // vmaddax.xyzw acc, vf7, vf13 - c->vmadd_bc(DEST::xyzw, BC::w, vf9, vf8, vf13); // vmaddw.xyzw vf9, vf8, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L13 // beq r0, r0, L13 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 32: - next_block = 33; - c->lq(a0, 0, sp); // lq a0, 0(sp) - c->lq(t7, 16, sp); // lq t7, 16(sp) - c->lq(s0, 32, sp); // lq s0, 32(sp) - c->lq(s1, 48, sp); // lq s1, 48(sp) - //jr ra // jr ra - c->daddiu(sp, sp, 64); // daddiu sp, sp, 64 - goto end_of_function; // return - - //jr ra // jr ra - c->daddu(sp, sp, r0); // daddu sp, sp, r0 - goto end_of_function; // return - - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - } - } - end_of_function: - return c->gprs[v0].du64[0]; -} - -u32 jump_table_vals[16] = { - 0x4d7666df, // = 6 ^ 1299605209 - 0x4d7666d0, // = 9 ^ 1299605209 - 0x4d7666d2, // = 11 ^ 1299605209 - 0x4d7666d7, // = 14 ^ 1299605209 - 0x4d7666cd, // = 20 ^ 1299605209 - 0x4d7666cc, // = 21 ^ 1299605209 - 0x4d7666ce, // = 23 ^ 1299605209 - 0x4d7666c3, // = 26 ^ 1299605209 - 0x4d7666df, // = 6 ^ 1299605209 - 0x4d7666d3, // = 10 ^ 1299605209 - 0x4d7666d2, // = 11 ^ 1299605209 - 0x4d7666c8, // = 17 ^ 1299605209 - 0x4d7666cd, // = 20 ^ 1299605209 - 0x4d7666cf, // = 22 ^ 1299605209 - 0x4d7666ce, // = 23 ^ 1299605209 - 0x4d7666c4, // = 29 ^ 1299605209 -}; - -} // namespace decompress_frame_data_pair_to_accumulator -} // namespace Mips2C - -//--------------------------MIPS2C--------------------- -#include "game/mips2c/mips2c_private.h" - -namespace Mips2C::jak1 { -namespace decompress_frame_data_to_accumulator { -u64 execute(void* ctxt) { - auto* c = (ExecutionContext*)ctxt; - bool bc = false; - u32 next_block = 0; - while(true) { - switch(next_block) { - - case 0: - next_block = 1; - c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 - c->mov128_vf_gpr(vf13, a2); // qmtc2.i vf13, a2 - c->sq(a0, 0, sp); // sq a0, 0(sp) - //c->lui(t2, 28672); // lui t2, 28672 - get_fake_spad_addr(t2, cache.fake_scratchpad_data, 0, c); - c->lw(t4, 0, a1); // lw t4, 0(a1) - c->daddiu(v1, a1, 16); // daddiu v1, a1, 16 - c->lw(t5, 4, a1); // lw t5, 4(a1) - c->daddu(s5, t1, r0); // daddu s5, t1, r0 - c->lw(t6, 8, a1); // lw t6, 8(a1) - c->daddu(t4, t4, v1); // daddu t4, t4, v1 - c->vmul_bc(DEST::xyzw, BC::x, vf13, vf14, vf13); // vmulx.xyzw vf13, vf14, vf13 - c->daddiu(t2, t2, 1696); // daddiu t2, t2, 1696 - c->lw(s2, 56, t1); // lw s2, 56(t1) - c->daddu(t5, t5, v1); // daddu t5, t5, v1 - c->lw(s4, 60, t1); // lw s4, 60(t1) - c->daddu(t6, t6, v1); // daddu t6, t6, v1 - c->addiu(s3, r0, 8); // addiu s3, r0, 8 - c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 - c->andi(t3, s4, 1); // andi t3, s4, 1 - // nop // sll r0, r0, 0 - bc = c->sgpr64(t3) == 0; // beq t3, r0, L22 - // nop // sll r0, r0, 0 - if (bc) {next_block = 2;} // branch non-likely - - break; - - case 1: - next_block = 2; - c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) - c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) - c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) - c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) - c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) - c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 - c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) - // nop // sll r0, r0, 0 - c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) - c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf1, vf13); // vmaddx.xyzw vf9, vf1, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf2, vf13); // vmaddx.xyzw vf10, vf2, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf11, vf3, vf13); // vmaddx.xyzw vf11, vf3, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf12, vf4, vf13); // vmaddx.xyzw vf12, vf4, vf13 - c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) - c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) - c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) - c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) - - case 2: - next_block = 3; - c->andi(t3, s4, 2); // andi t3, s4, 2 - c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 - bc = c->sgpr64(t3) == 0; // beq t3, r0, L23 - // nop // sll r0, r0, 0 - if (bc) {next_block = 4;} // branch non-likely - - break; - - case 3: - next_block = 4; - c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) - c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) - c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) - c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) - c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) - c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 - c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) - // nop // sll r0, r0, 0 - c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) - c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf1, vf13); // vmaddx.xyzw vf9, vf1, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf2, vf13); // vmaddx.xyzw vf10, vf2, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf11, vf3, vf13); // vmaddx.xyzw vf11, vf3, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf12, vf4, vf13); // vmaddx.xyzw vf12, vf4, vf13 - c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) - c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) - c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) - c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) - - case 4: - next_block = 5; - c->lw(s4, -4, s5); // lw s4, -4(s5) - c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 - - case 5: - next_block = 6; - c->andi(t3, s4, 15); // andi t3, s4, 15 - c->sra(s4, s4, 4); // sra s4, s4, 4 - c->sll(t3, t3, 2); // sll t3, t3, 2 - c->daddiu(s3, s3, -1); // daddiu s3, s3, -1 - c->daddu(t3, t3, t2); // daddu t3, t3, t2 - c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 - c->lw(t3, 0, t3); // lw t3, 0(t3) - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - next_block = 0x7b2191d ^ c->gprs[t3].du32[0]; // jr t3 - ASSERT(next_block < 33); - break; - // nop // sll r0, r0, 0 - - case 6: - next_block = 7; - bc = c->sgpr64(s2) == 0; // beq s2, r0, L32 - c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 - if (bc) {next_block = 32;} // branch non-likely - - break; - - case 7: - next_block = 8; - bc = c->sgpr64(s3) != 0; // bne s3, r0, L24 - // nop // sll r0, r0, 0 - if (bc) {next_block = 5;} // branch non-likely - - break; - - case 8: - next_block = 9; - c->lw(s4, 0, s5); // lw s4, 0(s5) - c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 - //beq r0, r0, L24 // beq r0, r0, L24 - c->addiu(s3, r0, 8); // addiu s3, r0, 8 - next_block = 5; // branch always - - break; - - case 9: - next_block = 10; - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 10: - next_block = 11; - c->ld(s6, 0, t4); // ld s6, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 11: - next_block = 12; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L26 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 13; - break; - } - - case 13: - next_block = 14; - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 14: - next_block = 15; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L27 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 16; - break; - } - - case 16: - next_block = 17; - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 17: - next_block = 18; - c->ld(t9, 8, t4); // ld t9, 8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(s6, -8, t4); // ld s6, -8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L28 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 19; - break; - } - - case 19: - next_block = 20; - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 20: - next_block = 21; - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 21: - next_block = 22; - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 22: - next_block = 23; - c->ld(s6, 0, t4); // ld s6, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 23: - next_block = 24; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L29 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 25; - break; - } - - case 25: - next_block = 26; - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 26: - next_block = 27; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L30 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 28; - break; - } - - case 28: - next_block = 29; - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 29: - next_block = 30; - c->ld(t9, 8, t4); // ld t9, 8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(s6, -8, t4); // ld s6, -8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L31 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 31; - break; - } - - case 31: - next_block = 32; - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L25 // beq r0, r0, L25 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 32: - next_block = 33; - c->lq(a0, 0, sp); // lq a0, 0(sp) - // nop // sll r0, r0, 0 - //jr ra // jr ra - c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 - goto end_of_function; // return - - //jr ra // jr ra - c->daddu(sp, sp, r0); // daddu sp, sp, r0 - goto end_of_function; // return - - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - } - } - end_of_function: - return c->gprs[v0].du64[0]; -} - -u32 jump_table_vals[16] = { - 0x7b2191b, // = 6 ^ 129112349 - 0x7b21914, // = 9 ^ 129112349 - 0x7b21916, // = 11 ^ 129112349 - 0x7b21913, // = 14 ^ 129112349 - 0x7b21909, // = 20 ^ 129112349 - 0x7b21908, // = 21 ^ 129112349 - 0x7b2190a, // = 23 ^ 129112349 - 0x7b21907, // = 26 ^ 129112349 - 0x7b2191b, // = 6 ^ 129112349 - 0x7b21917, // = 10 ^ 129112349 - 0x7b21916, // = 11 ^ 129112349 - 0x7b2190c, // = 17 ^ 129112349 - 0x7b21909, // = 20 ^ 129112349 - 0x7b2190b, // = 22 ^ 129112349 - 0x7b2190a, // = 23 ^ 129112349 - 0x7b21900, // = 29 ^ 129112349 -}; - -} // namespace decompress_frame_data_to_accumulator -} // namespace Mips2C - -//--------------------------MIPS2C--------------------- -#include "game/mips2c/mips2c_private.h" - -namespace Mips2C::jak1 { -namespace decompress_fixed_data_to_accumulator { -u64 execute(void* ctxt) { - auto* c = (ExecutionContext*)ctxt; - bool bc = false; - u32 next_block = 0; - while(true) { - switch(next_block) { - - case 0: - next_block = 1; - c->lq(t4, 0, a1); // lq t4, 0(a1) - c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 - c->lq(t5, 16, a1); // lq t5, 16(a1) - // nop // sll r0, r0, 0 - c->sq(t4, 0, t1); // sq t4, 0(t1) - // nop // sll r0, r0, 0 - c->sq(t5, 16, t1); // sq t5, 16(t1) - // nop // sll r0, r0, 0 - c->lq(t4, 32, a1); // lq t4, 32(a1) - // nop // sll r0, r0, 0 - c->lq(t5, 48, a1); // lq t5, 48(a1) - // nop // sll r0, r0, 0 - c->sq(t4, 32, t1); // sq t4, 32(t1) - // nop // sll r0, r0, 0 - c->sq(t5, 48, t1); // sq t5, 48(t1) - // nop // sll r0, r0, 0 - c->sq(a0, 0, sp); // sq a0, 0(sp) - // nop // sll r0, r0, 0 - c->mov128_vf_gpr(vf13, a2); // qmtc2.i vf13, a2 - // c->lui(t2, 28672); // lui t2, 28672 - get_fake_spad_addr(t2, cache.fake_scratchpad_data, 0, c); - c->lw(t4, 64, a1); // lw t4, 64(a1) - c->daddiu(v1, a1, 80); // daddiu v1, a1, 80 - c->lw(t5, 68, a1); // lw t5, 68(a1) - c->daddu(s5, t1, r0); // daddu s5, t1, r0 - c->lw(t6, 72, a1); // lw t6, 72(a1) - c->daddu(t4, t4, v1); // daddu t4, t4, v1 - c->vmul_bc(DEST::xyzw, BC::x, vf13, vf14, vf13); // vmulx.xyzw vf13, vf14, vf13 - c->daddiu(t2, t2, 1632); // daddiu t2, t2, 1632 - c->lw(s2, 56, t1); // lw s2, 56(t1) - c->daddu(t5, t5, v1); // daddu t5, t5, v1 - c->lw(s4, 60, t1); // lw s4, 60(t1) - c->daddu(t6, t6, v1); // daddu t6, t6, v1 - c->addiu(s3, r0, 8); // addiu s3, r0, 8 - c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 - c->andi(t3, s4, 1); // andi t3, s4, 1 - // nop // sll r0, r0, 0 - bc = c->sgpr64(t3) != 0; // bne t3, r0, L34 - // nop // sll r0, r0, 0 - if (bc) {next_block = 2;} // branch non-likely - - break; - - case 1: - next_block = 2; - c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) - c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) - c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) - c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) - c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) - c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 - c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) - // nop // sll r0, r0, 0 - c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) - c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf1, vf13); // vmaddx.xyzw vf9, vf1, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf2, vf13); // vmaddx.xyzw vf10, vf2, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf11, vf3, vf13); // vmaddx.xyzw vf11, vf3, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf12, vf4, vf13); // vmaddx.xyzw vf12, vf4, vf13 - c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) - c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) - c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) - c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) - - case 2: - next_block = 3; - c->andi(t3, s4, 2); // andi t3, s4, 2 - c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 - bc = c->sgpr64(t3) != 0; // bne t3, r0, L35 - // nop // sll r0, r0, 0 - if (bc) {next_block = 4;} // branch non-likely - - break; - - case 3: - next_block = 4; - c->lqc2(vf1, 0, t4); // lqc2 vf1, 0(t4) - c->lqc2(vf2, 16, t4); // lqc2 vf2, 16(t4) - c->lqc2(vf3, 32, t4); // lqc2 vf3, 32(t4) - c->lqc2(vf4, 48, t4); // lqc2 vf4, 48(t4) - c->lqc2(vf9, 0, a0); // lqc2 vf9, 0(a0) - c->daddiu(t4, t4, 64); // daddiu t4, t4, 64 - c->lqc2(vf10, 16, a0); // lqc2 vf10, 16(a0) - // nop // sll r0, r0, 0 - c->lqc2(vf11, 32, a0); // lqc2 vf11, 32(a0) - c->lqc2(vf12, 48, a0); // lqc2 vf12, 48(a0) - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf1, vf13); // vmaddx.xyzw vf9, vf1, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf2, vf13); // vmaddx.xyzw vf10, vf2, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf11, vf0); // vmulaw.xyzw acc, vf11, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf11, vf3, vf13); // vmaddx.xyzw vf11, vf3, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf12, vf0); // vmulaw.xyzw acc, vf12, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf12, vf4, vf13); // vmaddx.xyzw vf12, vf4, vf13 - c->sqc2(vf9, 0, a0); // sqc2 vf9, 0(a0) - c->sqc2(vf10, 16, a0); // sqc2 vf10, 16(a0) - c->sqc2(vf11, 32, a0); // sqc2 vf11, 32(a0) - c->sqc2(vf12, 48, a0); // sqc2 vf12, 48(a0) - - case 4: - next_block = 5; - c->lw(s4, -4, s5); // lw s4, -4(s5) - c->daddiu(a0, a0, 64); // daddiu a0, a0, 64 - - case 5: - next_block = 6; - c->andi(t3, s4, 15); // andi t3, s4, 15 - c->sra(s4, s4, 4); // sra s4, s4, 4 - c->sll(t3, t3, 2); // sll t3, t3, 2 - c->daddiu(s3, s3, -1); // daddiu s3, s3, -1 - c->daddu(t3, t3, t2); // daddu t3, t3, t2 - c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 - c->lw(t3, 0, t3); // lw t3, 0(t3) - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - next_block = 0x3ee6b6f0 ^ c->gprs[t3].du32[0]; // jr t3 - ASSERT(next_block < 33); - break; - // nop // sll r0, r0, 0 - - case 6: - next_block = 7; - bc = c->sgpr64(s2) == 0; // beq s2, r0, L44 - c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 - if (bc) {next_block = 32;} // branch non-likely - - break; - - case 7: - next_block = 8; - bc = c->sgpr64(s3) != 0; // bne s3, r0, L36 - // nop // sll r0, r0, 0 - if (bc) {next_block = 5;} // branch non-likely - - break; - - case 8: - next_block = 9; - c->lw(s4, 0, s5); // lw s4, 0(s5) - c->daddiu(s5, s5, 4); // daddiu s5, s5, 4 - //beq r0, r0, L36 // beq r0, r0, L36 - c->addiu(s3, r0, 8); // addiu s3, r0, 8 - next_block = 5; // branch always - - break; - - case 9: - next_block = 10; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L38 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 11; - break; - } - - case 11: - next_block = 12; - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 12: - next_block = 13; - c->ld(t9, 8, t4); // ld t9, 8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(s6, -8, t4); // ld s6, -8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L39 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 14; - break; - } - - case 14: - next_block = 15; - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 15: - next_block = 16; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L40 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 17; - break; - } - - case 17: - next_block = 18; - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 18: - next_block = 19; - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 19: - next_block = 20; - c->ld(s6, 0, t4); // ld s6, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 20: - next_block = 21; - c->lw(t8, 0, t5); // lw t8, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(fp, 0, t6); // lh fp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf9, 32, a0); // lqc2 vf9, 32(a0) - c->pextlw(t8, fp, t8); // pextlw t8, fp, t8 - c->pextlh(t8, t8, r0); // pextlh t8, t8, r0 - c->psraw(t8, t8, 16); // psraw t8, t8, 16 - c->mov128_vf_gpr(vf7, t8); // qmtc2.i vf7, t8 - c->vitof12(DEST::xyzw, vf7, vf7); // vitof12.xyzw vf7, vf7 - c->vmula_bc(DEST::xyzw, BC::w, vf9, vf0); // vmulaw.xyzw acc, vf9, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf9, vf7, vf13); // vmaddx.xyzw vf9, vf7, vf13 - c->sqc2(vf9, 32, a0); // sqc2 vf9, 32(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 21: - next_block = 22; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L41 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 23; - break; - } - - case 23: - next_block = 24; - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 24: - next_block = 25; - c->ld(t9, 8, t4); // ld t9, 8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->ld(s6, -8, t4); // ld s6, -8(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L42 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 26; - break; - } - - case 26: - next_block = 27; - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 27: - next_block = 28; - c->ld(t9, 0, t4); // ld t9, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lqc2(vf6, 16, a0); // lqc2 vf6, 16(a0) - c->pextlh(t9, t9, r0); // pextlh t9, t9, r0 - c->psraw(t9, t9, 16); // psraw t9, t9, 16 - c->mov128_vf_gpr(vf4, t9); // qmtc2.i vf4, t9 - c->vitof15(DEST::xyzw, vf4, vf4); // vitof15.xyzw vf4, vf4 - c->vmul(DEST::xyzw, vf10, vf4, vf6); // vmul.xyzw vf10, vf4, vf6 - c->vmula_bc(DEST::xyzw, BC::w, vf10, vf0); // vmulaw.xyzw acc, vf10, vf0 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->mov128_gpr_vf(t9, vf10); // qmfc2.i t9, vf10 - c->pcpyud(t9, t9, r0); // pcpyud t9, t9, r0 - if (((s64)c->sgpr64(t9)) < 0) { // bltzl t9, L43 - c->vsub(DEST::xyzw, vf4, vf15, vf4); // vsub.xyzw vf4, vf15, vf4 - next_block = 29; - break; - } - - case 29: - next_block = 30; - c->vmula_bc(DEST::xyzw, BC::w, vf6, vf0); // vmulaw.xyzw acc, vf6, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf6, vf4, vf13); // vmaddx.xyzw vf6, vf4, vf13 - c->sqc2(vf6, 16, a0); // sqc2 vf6, 16(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 30: - next_block = 31; - c->lw(s6, 0, t5); // lw s6, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lh(gp, 0, t6); // lh gp, 0(t6) - c->daddiu(t6, t6, 2); // daddiu t6, t6, 2 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pextlw(s6, gp, s6); // pextlw s6, gp, s6 - c->pextlh(s6, s6, r0); // pextlh s6, s6, r0 - c->psraw(s6, s6, 16); // psraw s6, s6, 16 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vitof0(DEST::xyzw, vf1, vf1); // vitof0.xyzw vf1, vf1 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::y, vf3, vf1, vf13); // vmaddy.xyzw vf3, vf1, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 31: - next_block = 32; - c->ld(s6, 0, t4); // ld s6, 0(t4) - c->daddiu(t4, t4, 8); // daddiu t4, t4, 8 - c->lw(gp, 0, t5); // lw gp, 0(t5) - c->daddiu(t5, t5, 4); // daddiu t5, t5, 4 - c->lqc2(vf3, 0, a0); // lqc2 vf3, 0(a0) - c->pcpyld(s6, gp, s6); // pcpyld s6, gp, s6 - c->mov128_vf_gpr(vf1, s6); // qmtc2.i vf1, s6 - c->vmula_bc(DEST::xyzw, BC::w, vf3, vf0); // vmulaw.xyzw acc, vf3, vf0 - c->vmadd_bc(DEST::xyzw, BC::x, vf3, vf1, vf13); // vmaddx.xyzw vf3, vf1, vf13 - c->sqc2(vf3, 0, a0); // sqc2 vf3, 0(a0) - //beq r0, r0, L37 // beq r0, r0, L37 - // nop // sll r0, r0, 0 - next_block = 6; // branch always - - break; - - case 32: - next_block = 33; - c->lq(a0, 0, sp); // lq a0, 0(sp) - // nop // sll r0, r0, 0 - //jr ra // jr ra - c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 - goto end_of_function; // return - - //jr ra // jr ra - c->daddu(sp, sp, r0); // daddu sp, sp, r0 - goto end_of_function; // return - - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - } - } - end_of_function: - return c->gprs[v0].du64[0]; -} - -u32 jump_table_vals[16] = { - 0x3ee6b6f9, // = 9 ^ 1055307504 - 0x3ee6b6ff, // = 15 ^ 1055307504 - 0x3ee6b6e2, // = 18 ^ 1055307504 - 0x3ee6b6e4, // = 20 ^ 1055307504 - 0x3ee6b6e5, // = 21 ^ 1055307504 - 0x3ee6b6eb, // = 27 ^ 1055307504 - 0x3ee6b6ee, // = 30 ^ 1055307504 - 0x3ee6b6f6, // = 6 ^ 1055307504 - 0x3ee6b6fc, // = 12 ^ 1055307504 - 0x3ee6b6ff, // = 15 ^ 1055307504 - 0x3ee6b6e3, // = 19 ^ 1055307504 - 0x3ee6b6e4, // = 20 ^ 1055307504 - 0x3ee6b6e8, // = 24 ^ 1055307504 - 0x3ee6b6eb, // = 27 ^ 1055307504 - 0x3ee6b6ef, // = 31 ^ 1055307504 - 0x3ee6b6f6, // = 6 ^ 1055307504 -}; - -} // namespace decompress_fixed_data_to_accumulator -} // namespace Mips2C - -//--------------------------MIPS2C--------------------- -#include "game/mips2c/mips2c_private.h" - -namespace Mips2C::jak1 { -namespace normalize_frame_quaternions { -u64 execute(void* ctxt) { - auto* c = (ExecutionContext*)ctxt; - bool bc = false; - c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 - c->daddiu(s2, s2, -2); // daddiu s2, s2, -2 - c->sw(a0, 0, sp); // sw a0, 0(sp) - c->daddiu(a0, a0, 128); // daddiu a0, a0, 128 - - block_1: - c->lqc2(vf4, 16, a0); // lqc2 vf4, 16(a0) - c->lqc2(vf1, 0, a0); // lqc2 vf1, 0(a0) - c->lqc2(vf7, 32, a0); // lqc2 vf7, 32(a0) - c->vmul(DEST::xyzw, vf10, vf4, vf4); // vmul.xyzw vf10, vf4, vf4 - c->vmove(DEST::w, vf1, vf0); // vmove.w vf1, vf0 - c->vmove(DEST::w, vf7, vf0); // vmove.w vf7, vf0 - c->vmula_bc(DEST::xyzw, BC::w, vf0, vf10); // vmulaw.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::z, vf0, vf10); // vmaddaz.xyzw acc, vf0, vf10 - c->vmadda_bc(DEST::xyzw, BC::y, vf0, vf10); // vmadday.xyzw acc, vf0, vf10 - c->vmadd_bc(DEST::xyzw, BC::x, vf10, vf0, vf10); // vmaddx.xyzw vf10, vf0, vf10 - c->sqc2(vf1, 0, a0); // sqc2 vf1, 0(a0) - c->sqc2(vf7, 32, a0); // sqc2 vf7, 32(a0) - c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 - c->vrsqrt(vf0, BC::w, vf10, BC::w); // vrsqrt Q, vf0.w, vf10.w - c->vwaitq(); // vwaitq - c->vmulq(DEST::xyzw, vf4, vf4); // vmulq.xyzw vf4, vf4, Q - c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 - bc = c->sgpr64(s2) != 0; // bne s2, r0, L46 - c->sqc2(vf4, -32, a0); // sqc2 vf4, -32(a0) - if (bc) {goto block_1;} // branch non-likely - - c->lw(a0, 0, sp); // lw a0, 0(sp) - // nop // sll r0, r0, 0 - //jr ra // jr ra - c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 - goto end_of_function; // return - - //jr ra // jr ra - c->daddu(sp, sp, r0); // daddu sp, sp, r0 - goto end_of_function; // return - - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - end_of_function: - return c->gprs[v0].du64[0]; -} - -} // namespace normalize_frame_quaternions -} // namespace Mips2C - -//--------------------------MIPS2C--------------------- -#include "game/mips2c/mips2c_private.h" - -namespace Mips2C::jak1 { -namespace clear_frame_accumulator { -u64 execute(void* ctxt) { - auto* c = (ExecutionContext*)ctxt; - bool bc = false; - c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 - // nop // sll r0, r0, 0 - c->sw(a0, 0, sp); // sw a0, 0(sp) - // nop // sll r0, r0, 0 - c->sq(r0, 0, a0); // sq r0, 0(a0) - c->daddiu(s2, s2, -2); // daddiu s2, s2, -2 - c->sq(r0, 16, a0); // sq r0, 16(a0) - // nop // sll r0, r0, 0 - c->sq(r0, 32, a0); // sq r0, 32(a0) - // nop // sll r0, r0, 0 - c->sq(r0, 48, a0); // sq r0, 48(a0) - // nop // sll r0, r0, 0 - c->sq(r0, 64, a0); // sq r0, 64(a0) - // nop // sll r0, r0, 0 - c->sq(r0, 80, a0); // sq r0, 80(a0) - // nop // sll r0, r0, 0 - c->sq(r0, 96, a0); // sq r0, 96(a0) - // nop // sll r0, r0, 0 - c->sq(r0, 112, a0); // sq r0, 112(a0) - c->daddiu(a0, a0, 128); // daddiu a0, a0, 128 - - block_1: - c->sq(r0, 0, a0); // sq r0, 0(a0) - c->daddiu(s2, s2, -1); // daddiu s2, s2, -1 - c->sq(r0, 16, a0); // sq r0, 16(a0) - c->daddiu(a0, a0, 48); // daddiu a0, a0, 48 - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - bc = c->sgpr64(s2) != 0; // bne s2, r0, L48 - c->sq(r0, -16, a0); // sq r0, -16(a0) - if (bc) {goto block_1;} // branch non-likely - - c->lw(a0, 0, sp); // lw a0, 0(sp) - // nop // sll r0, r0, 0 - //jr ra // jr ra - c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 - goto end_of_function; // return - - //jr ra // jr ra - c->daddu(sp, sp, r0); // daddu sp, sp, r0 - goto end_of_function; // return - - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - end_of_function: - return c->gprs[v0].du64[0]; -} -} // namespace clear_frame_accumulator -} // namespace Mips2C - - -//--------------------------MIPS2C--------------------- -#include "game/mips2c/mips2c_private.h" - -namespace Mips2C::jak1 { -namespace calc_animation_from_spr { - - -u64 execute(void* ctxt) { - auto* c = (ExecutionContext*)ctxt; - bool bc = false; - [[maybe_unused]] u32 call_addr = 0; - u32 madr, sadr, qwc; - c->mov64(v1, a1); // or v1, a1, r0 - c->daddiu(sp, sp, -192); // daddiu sp, sp, -192 - c->sq(s0, 0, sp); // sq s0, 0(sp) - c->sq(s1, 16, sp); // sq s1, 16(sp) - c->sq(s2, 32, sp); // sq s2, 32(sp) - c->sq(s3, 48, sp); // sq s3, 48(sp) - c->sq(s4, 64, sp); // sq s4, 64(sp) - c->sq(s5, 80, sp); // sq s5, 80(sp) - c->sq(s6, 96, sp); // sq s6, 96(sp) - c->sq(t8, 112, sp); // sq t8, 112(sp) - c->sq(t9, 128, sp); // sq t9, 128(sp) - c->sq(gp, 144, sp); // sq gp, 144(sp) - c->sq(fp, 160, sp); // sq fp, 160(sp) - c->sq(ra, 176, sp); // sq ra, 176(sp) - c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 - c->mov128_vf_gpr(vf15, r0); // qmtc2.i vf15, r0 - c->sw(a1, 0, sp); // sw a1, 0(sp) - //c->lui(v1, 28672); // lui v1, 28672 - get_fake_spad_addr(v1, cache.fake_scratchpad_data, 0, c); - c->lw(s1, 2400, v1); // lw s1, 2400(v1) - c->daddiu(t7, v1, 1824); // daddiu t7, v1, 1824 - c->lui(s0, 4096); // lui s0, 4096 - c->daddiu(t1, v1, 7344); // daddiu t1, v1, 7344 - bc = c->sgpr64(s1) == 0; // beq s1, r0, L7 - c->ori(s0, s0, 54272); // ori s0, s0, 54272 // spr to (d400) - if (bc) {goto block_12;} // branch non-likely - - c->lw(t2, 0, t7); // lw t2, 0(t7) - c->addiu(t3, r0, 7408); // addiu t3, r0, 7408 - c->lw(t4, 4, t7); // lw t4, 4(t7) - c->addiu(v1, r0, 256); // addiu v1, r0, 256 - // c->sw(t2, 16, s0); // sw t2, 16(s0) - madr = c->sgpr64(t2); - c->vadd_bc(DEST::xyzw, BC::w, vf14, vf15, vf0); // vaddw.xyzw vf14, vf15, vf0 - //c->sw(t3, 128, s0); // sw t3, 128(s0) - sadr = c->sgpr64(t3); - // nop // sll r0, r0, 0 - //c->sw(t4, 32, s0); // sw t4, 32(s0) - qwc = c->sgpr64(t4); - // Unknown instr: sync.l - //c->sw(v1, 0, s0); // sw v1, 0(s0) - spad_to_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); - // Unknown instr: sync.l - c->load_symbol(t9, cache.clear_frame_accumulator);// lw t9, clear-frame-accumulator(s7) - c->vadd(DEST::yz, vf14, vf14, vf14); // vadd.yz vf14, vf14, vf14 - c->lw(s2, 0, sp); // lw s2, 0(sp) - // nop // sll r0, r0, 0 - call_addr = c->gprs[t9].du32[0]; // function call: - c->vadd(DEST::yz, vf14, vf14, vf14); // vadd.yz vf14, vf14, vf14 - //c->jalr(call_addr); // jalr ra, t9 - clear_frame_accumulator::execute(c); - - block_2: -// c->lw(v1, 0, s0); // lw v1, 0(s0) -// // nop // sll r0, r0, 0 -// c->andi(v1, v1, 256); // andi v1, v1, 256 -// // nop // sll r0, r0, 0 -// // nop // sll r0, r0, 0 -// // nop // sll r0, r0, 0 -// bc = c->sgpr64(v1) != 0; // bne v1, r0, L3 -// // nop // sll r0, r0, 0 -// if (bc) {goto block_2;} // branch non-likely - - c->lw(t2, 8, t7); // lw t2, 8(t7) - c->addiu(t3, r0, 9616); // addiu t3, r0, 9616 - c->lw(t4, 12, t7); // lw t4, 12(t7) - c->addiu(v1, r0, 256); // addiu v1, r0, 256 - //c->sw(t2, 16, s0); // sw t2, 16(s0) - madr = c->sgpr64(t2); - // nop // sll r0, r0, 0 - //c->sw(t3, 128, s0); // sw t3, 128(s0) - sadr = c->sgpr64(t3); - // nop // sll r0, r0, 0 - //c->sw(t4, 32, s0); // sw t4, 32(s0) - qwc = c->sgpr64(t4); - // Unknown instr: sync.l - //c->sw(v1, 0, s0); // sw v1, 0(s0) - spad_to_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); - // Unknown instr: sync.l - c->lw(a2, 16, t7); // lw a2, 16(t7) - //c->lui(a1, 28672); // lui a1, 28672 - get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c); - c->load_symbol(t9, cache.decompress_fixed_data_to_accumulator);// lw t9, decompress-fixed-data-to-accumulator(s7) - c->daddiu(a1, a1, 7408); // daddiu a1, a1, 7408 - call_addr = c->gprs[t9].du32[0]; // function call: - c->daddiu(s1, s1, -1); // daddiu s1, s1, -1 - //c->jalr(call_addr); // jalr ra, t9 - decompress_fixed_data_to_accumulator::execute(c); - -// block_4: -// c->lw(v1, 0, s0); // lw v1, 0(s0) -// // nop // sll r0, r0, 0 -// c->andi(v1, v1, 256); // andi v1, v1, 256 -// // nop // sll r0, r0, 0 -// // nop // sll r0, r0, 0 -// // nop // sll r0, r0, 0 -// bc = c->sgpr64(v1) != 0; // bne v1, r0, L4 -// // nop // sll r0, r0, 0 -// if (bc) {goto block_4;} // branch non-likely - - bc = c->sgpr64(s1) == 0; // beq s1, r0, L5 - // nop // sll r0, r0, 0 - if (bc) {goto block_7;} // branch non-likely - - c->lw(t2, 24, t7); // lw t2, 24(t7) - c->addiu(t3, r0, 7408); // addiu t3, r0, 7408 - c->lw(t4, 28, t7); // lw t4, 28(t7) - c->addiu(v1, r0, 256); // addiu v1, r0, 256 - //c->sw(t2, 16, s0); // sw t2, 16(s0) - madr = c->sgpr64(t2); - // nop // sll r0, r0, 0 - //c->sw(t3, 128, s0); // sw t3, 128(s0) - sadr = c->sgpr64(t3); - // nop // sll r0, r0, 0 - //c->sw(t4, 32, s0); // sw t4, 32(s0) - qwc = c->sgpr64(t4); - // Unknown instr: sync.l - //c->sw(v1, 0, s0); // sw v1, 0(s0) - spad_to_dma_no_sadr_off(cache.fake_scratchpad_data, madr, sadr, qwc); - // Unknown instr: sync.l - - block_7: - c->lw(t0, 20, t7); // lw t0, 20(t7) - //c->lui(a1, 28672); // lui a1, 28672 - get_fake_spad_addr(a1, cache.fake_scratchpad_data, 0, c); - c->lw(a2, 16, t7); // lw a2, 16(t7) - c->daddiu(a1, a1, 9616); // daddiu a1, a1, 9616 - bc = c->sgpr64(t0) == 0; // beq t0, r0, L6 - // nop // sll r0, r0, 0 - if (bc) {goto block_10;} // branch non-likely - - c->lw(a3, 12, t7); // lw a3, 12(t7) - // nop // sll r0, r0, 0 - c->load_symbol(t9, cache.decompress_frame_data_pair_to_accumulator);// lw t9, decompress-frame-data-pair-to-accumulator(s7) - // nop // sll r0, r0, 0 - call_addr = c->gprs[t9].du32[0]; // function call: - c->sll(a3, a3, 3); // sll a3, a3, 3 - //c->jalr(call_addr); // jalr ra, t9 - decompress_frame_data_pair_to_accumulator::execute(c); - bc = c->sgpr64(s1) != 0; // bne s1, r0, L3 - c->daddiu(t7, t7, 24); // daddiu t7, t7, 24 - if (bc) {goto block_2;} // branch non-likely - - c->load_symbol(t9, cache.normalize_frame_quaternions);// lw t9, normalize-frame-quaternions(s7) - // nop // sll r0, r0, 0 - c->lw(s2, 0, sp); // lw s2, 0(sp) - // nop // sll r0, r0, 0 - call_addr = c->gprs[t9].du32[0]; // function call: - // nop // sll r0, r0, 0 - //c->jalr(call_addr); // jalr ra, t9 - normalize_frame_quaternions::execute(c); - c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 - // nop // sll r0, r0, 0 - c->lq(s0, 0, sp); // lq s0, 0(sp) - c->lq(s1, 16, sp); // lq s1, 16(sp) - c->lq(s2, 32, sp); // lq s2, 32(sp) - c->lq(s3, 48, sp); // lq s3, 48(sp) - c->lq(s4, 64, sp); // lq s4, 64(sp) - c->lq(s5, 80, sp); // lq s5, 80(sp) - c->lq(s6, 96, sp); // lq s6, 96(sp) - c->lq(t8, 112, sp); // lq t8, 112(sp) - c->lq(t9, 128, sp); // lq t9, 128(sp) - c->lq(gp, 144, sp); // lq gp, 144(sp) - c->lq(ra, 176, sp); // lq ra, 176(sp) - c->lq(fp, 160, sp); // lq fp, 160(sp) - //jr ra // jr ra - c->daddiu(sp, sp, 192); // daddiu sp, sp, 192 - goto end_of_function; // return - - - block_10: - c->load_symbol(t9, cache.decompress_frame_data_to_accumulator);// lw t9, decompress-frame-data-to-accumulator(s7) - // nop // sll r0, r0, 0 - call_addr = c->gprs[t9].du32[0]; // function call: - // nop // sll r0, r0, 0 - //c->jalr(call_addr); // jalr ra, t9 - decompress_frame_data_to_accumulator::execute(c); - bc = c->sgpr64(s1) != 0; // bne s1, r0, L3 - c->daddiu(t7, t7, 24); // daddiu t7, t7, 24 - if (bc) {goto block_2;} // branch non-likely - - c->load_symbol(t9, cache.normalize_frame_quaternions);// lw t9, normalize-frame-quaternions(s7) - // nop // sll r0, r0, 0 - c->lw(s2, 0, sp); // lw s2, 0(sp) - // nop // sll r0, r0, 0 - call_addr = c->gprs[t9].du32[0]; // function call: - // nop // sll r0, r0, 0 - //c->jalr(call_addr); // jalr ra, t9 - normalize_frame_quaternions::execute(c); - - block_12: - c->daddiu(sp, sp, 16); // daddiu sp, sp, 16 - // nop // sll r0, r0, 0 - c->lq(s0, 0, sp); // lq s0, 0(sp) - c->lq(s1, 16, sp); // lq s1, 16(sp) - c->lq(s2, 32, sp); // lq s2, 32(sp) - c->lq(s3, 48, sp); // lq s3, 48(sp) - c->lq(s4, 64, sp); // lq s4, 64(sp) - c->lq(s5, 80, sp); // lq s5, 80(sp) - c->lq(s6, 96, sp); // lq s6, 96(sp) - c->lq(t8, 112, sp); // lq t8, 112(sp) - c->lq(t9, 128, sp); // lq t9, 128(sp) - c->lq(gp, 144, sp); // lq gp, 144(sp) - c->lq(ra, 176, sp); // lq ra, 176(sp) - c->lq(fp, 160, sp); // lq fp, 160(sp) - //jr ra // jr ra - c->daddiu(sp, sp, 192); // daddiu sp, sp, 192 - goto end_of_function; // return - - //jr ra // jr ra - c->daddu(sp, sp, r0); // daddu sp, sp, r0 - goto end_of_function; // return - - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - end_of_function: - return c->gprs[v0].du64[0]; -} - -void link() { - cache.clear_frame_accumulator = intern_from_c("clear-frame-accumulator").c(); - cache.decompress_fixed_data_to_accumulator = intern_from_c("decompress-fixed-data-to-accumulator").c(); - cache.decompress_frame_data_pair_to_accumulator = intern_from_c("decompress-frame-data-pair-to-accumulator").c(); - cache.decompress_frame_data_to_accumulator = intern_from_c("decompress-frame-data-to-accumulator").c(); - cache.normalize_frame_quaternions = intern_from_c("normalize-frame-quaternions").c(); - cache.fake_scratchpad_data = intern_from_c("*fake-scratchpad-data*").c(); - - gLinkedFunctionTable.reg("calc-animation-from-spr", execute, 1024); -} - -} // namespace calc_animation_from_spr -} // namespace Mips2C - -//--------------------------MIPS2C--------------------- -#include "game/mips2c/mips2c_private.h" - -namespace Mips2C::jak1 { -namespace cspace_parented_transformq_joint { -u64 execute(void* ctxt) { - auto* c = (ExecutionContext*)ctxt; - bool bc = false; - // nop // sll r0, r0, 0 - c->lw(a3, 0, a0); // lw a3, 0(a0) - c->lui(v1, 16256); // lui v1, 16256 - c->lqc2(vf5, 16, a1); // lqc2 vf5, 16(a1) - c->mtc1(f0, v1); // mtc1 f0, v1 - c->lw(t0, 16, a3); // lw t0, 16(a3) - // nop // sll r0, r0, 0 - c->lw(a2, 16, a0); // lw a2, 16(a0) - c->vadd(DEST::xyzw, vf6, vf5, vf5); // vadd.xyzw vf6, vf5, vf5 - c->lwc1(f1, 64, t0); // lwc1 f1, 64(t0) - c->vadd_bc(DEST::x, BC::w, vf2, vf0, vf5); // vaddw.x vf2, vf0, vf5 - c->lqc2(vf15, 0, a1); // lqc2 vf15, 0(a1) - c->vadd_bc(DEST::y, BC::z, vf2, vf0, vf5); // vaddz.y vf2, vf0, vf5 - c->lqc2(vf1, 32, a1); // lqc2 vf1, 32(a1) - c->divs_accurate(f4, f0, f1); // div.s f4, f0, f1 - c->lqc2(vf7, 0, t0); // lqc2 vf7, 0(t0) - c->vsub_bc(DEST::z, BC::y, vf2, vf0, vf5); // vsuby.z vf2, vf0, vf5 - c->lqc2(vf8, 16, t0); // lqc2 vf8, 16(t0) - c->vsub_bc(DEST::w, BC::w, vf2, vf0, vf0); // vsubw.w vf2, vf0, vf0 - c->lqc2(vf9, 32, t0); // lqc2 vf9, 32(t0) - c->vsub_bc(DEST::x, BC::z, vf3, vf0, vf5); // vsubz.x vf3, vf0, vf5 - c->lqc2(vf10, 48, t0); // lqc2 vf10, 48(t0) - c->vadd_bc(DEST::y, BC::w, vf3, vf0, vf5); // vaddw.y vf3, vf0, vf5 - c->lwc1(f2, 68, t0); // lwc1 f2, 68(t0) - c->vadd_bc(DEST::z, BC::x, vf3, vf0, vf5); // vaddx.z vf3, vf0, vf5 - c->sqc2(vf1, 64, a2); // sqc2 vf1, 64(a2) - c->vsub_bc(DEST::w, BC::w, vf3, vf0, vf0); // vsubw.w vf3, vf0, vf0 - c->lwc1(f3, 72, t0); // lwc1 f3, 72(t0) - c->vadd_bc(DEST::x, BC::y, vf4, vf0, vf5); // vaddy.x vf4, vf0, vf5 - c->lw(v1, 76, t0); // lw v1, 76(t0) - c->vsub_bc(DEST::y, BC::x, vf4, vf0, vf5); // vsubx.y vf4, vf0, vf5 - c->mfc1(t1, f4); // mfc1 t1, f4 - c->vadd_bc(DEST::z, BC::w, vf4, vf0, vf5); // vaddw.z vf4, vf0, vf5 - c->divs_accurate(f4, f0, f2); // div.s f4, f0, f2 - c->vsub_bc(DEST::w, BC::w, vf4, vf0, vf0); // vsubw.w vf4, vf0, vf0 - c->vopmula(vf6, vf2); // vopmula.xyz acc, vf6, vf2 - c->vopmsub(vf2, vf2, vf6); // vopmsub.xyz vf2, vf2, vf6 - c->vopmula(vf6, vf3); // vopmula.xyz acc, vf6, vf3 - c->vopmsub(vf3, vf3, vf6); // vopmsub.xyz vf3, vf3, vf6 - c->vopmula(vf6, vf4); // vopmula.xyz acc, vf6, vf4 - c->vopmsub(vf4, vf4, vf6); // vopmsub.xyz vf4, vf4, vf6 - c->vadd_bc(DEST::x, BC::w, vf2, vf2, vf0); // vaddw.x vf2, vf2, vf0 - c->vadd_bc(DEST::y, BC::w, vf3, vf3, vf0); // vaddw.y vf3, vf3, vf0 - c->vadd_bc(DEST::z, BC::w, vf4, vf4, vf0); // vaddw.z vf4, vf4, vf0 - c->mfc1(t2, f4); // mfc1 t2, f4 - bc = c->sgpr64(v1) != 0; // bne v1, r0, L50 - c->divs_accurate(f4, f0, f3); // div.s f4, f0, f3 - if (bc) {goto block_2;} // branch non-likely - - c->vmul_bc(DEST::xyzw, BC::x, vf2, vf2, vf1); // vmulx.xyzw vf2, vf2, vf1 - c->vmul_bc(DEST::xyzw, BC::y, vf3, vf3, vf1); // vmuly.xyzw vf3, vf3, vf1 - c->vmul_bc(DEST::xyzw, BC::z, vf4, vf4, vf1); // vmulz.xyzw vf4, vf4, vf1 - c->vmula_bc(DEST::xyzw, BC::x, vf7, vf2); // vmulax.xyzw acc, vf7, vf2 - c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf2); // vmadday.xyzw acc, vf8, vf2 - c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf2); // vmaddaz.xyzw acc, vf9, vf2 - c->vmadd_bc(DEST::xyzw, BC::w, vf11, vf10, vf2); // vmaddw.xyzw vf11, vf10, vf2 - c->vmula_bc(DEST::xyzw, BC::x, vf7, vf3); // vmulax.xyzw acc, vf7, vf3 - c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf3); // vmadday.xyzw acc, vf8, vf3 - c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf3); // vmaddaz.xyzw acc, vf9, vf3 - c->vmadd_bc(DEST::xyzw, BC::w, vf12, vf10, vf3); // vmaddw.xyzw vf12, vf10, vf3 - c->vmula_bc(DEST::xyzw, BC::x, vf7, vf4); // vmulax.xyzw acc, vf7, vf4 - c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf4); // vmadday.xyzw acc, vf8, vf4 - c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf4); // vmaddaz.xyzw acc, vf9, vf4 - c->vmadd_bc(DEST::xyzw, BC::w, vf13, vf10, vf4); // vmaddw.xyzw vf13, vf10, vf4 - c->vmula_bc(DEST::xyzw, BC::x, vf7, vf15); // vmulax.xyzw acc, vf7, vf15 - c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf15); // vmadday.xyzw acc, vf8, vf15 - c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf15); // vmaddaz.xyzw acc, vf9, vf15 - c->vmadd_bc(DEST::xyzw, BC::w, vf14, vf10, vf0); // vmaddw.xyzw vf14, vf10, vf0 - c->sqc2(vf11, 0, a2); // sqc2 vf11, 0(a2) - c->sqc2(vf12, 16, a2); // sqc2 vf12, 16(a2) - c->sqc2(vf13, 32, a2); // sqc2 vf13, 32(a2) - c->sqc2(vf14, 48, a2); // sqc2 vf14, 48(a2) - //jr ra // jr ra - // nop // sll r0, r0, 0 - goto end_of_function; // return - - - block_2: - c->pextlw(t1, t2, t1); // pextlw t1, t2, t1 - c->vmul_bc(DEST::xyzw, BC::x, vf2, vf2, vf1); // vmulx.xyzw vf2, vf2, vf1 - c->vmul_bc(DEST::xyzw, BC::y, vf3, vf3, vf1); // vmuly.xyzw vf3, vf3, vf1 - c->vmul_bc(DEST::xyzw, BC::z, vf4, vf4, vf1); // vmulz.xyzw vf4, vf4, vf1 - c->mfc1(t3, f4); // mfc1 t3, f4 - c->pcpyld(t1, t3, t1); // pcpyld t1, t3, t1 - c->mov128_vf_gpr(vf16, t1); // qmtc2.i vf16, t1 - c->vmul(DEST::xyzw, vf2, vf2, vf16); // vmul.xyzw vf2, vf2, vf16 - c->vmul(DEST::xyzw, vf3, vf3, vf16); // vmul.xyzw vf3, vf3, vf16 - c->vmul(DEST::xyzw, vf4, vf4, vf16); // vmul.xyzw vf4, vf4, vf16 - c->vmula_bc(DEST::xyzw, BC::x, vf7, vf2); // vmulax.xyzw acc, vf7, vf2 - c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf2); // vmadday.xyzw acc, vf8, vf2 - c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf2); // vmaddaz.xyzw acc, vf9, vf2 - c->vmadd_bc(DEST::xyzw, BC::w, vf11, vf10, vf2); // vmaddw.xyzw vf11, vf10, vf2 - c->vmula_bc(DEST::xyzw, BC::x, vf7, vf3); // vmulax.xyzw acc, vf7, vf3 - c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf3); // vmadday.xyzw acc, vf8, vf3 - c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf3); // vmaddaz.xyzw acc, vf9, vf3 - c->vmadd_bc(DEST::xyzw, BC::w, vf12, vf10, vf3); // vmaddw.xyzw vf12, vf10, vf3 - c->vmula_bc(DEST::xyzw, BC::x, vf7, vf4); // vmulax.xyzw acc, vf7, vf4 - c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf4); // vmadday.xyzw acc, vf8, vf4 - c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf4); // vmaddaz.xyzw acc, vf9, vf4 - c->vmadd_bc(DEST::xyzw, BC::w, vf13, vf10, vf4); // vmaddw.xyzw vf13, vf10, vf4 - c->vmula_bc(DEST::xyzw, BC::x, vf7, vf15); // vmulax.xyzw acc, vf7, vf15 - c->vmadda_bc(DEST::xyzw, BC::y, vf8, vf15); // vmadday.xyzw acc, vf8, vf15 - c->vmadda_bc(DEST::xyzw, BC::z, vf9, vf15); // vmaddaz.xyzw acc, vf9, vf15 - c->vmadd_bc(DEST::xyzw, BC::w, vf14, vf10, vf0); // vmaddw.xyzw vf14, vf10, vf0 - c->sqc2(vf11, 0, a2); // sqc2 vf11, 0(a2) - c->sqc2(vf12, 16, a2); // sqc2 vf12, 16(a2) - c->sqc2(vf13, 32, a2); // sqc2 vf13, 32(a2) - c->sqc2(vf14, 48, a2); // sqc2 vf14, 48(a2) - //jr ra // jr ra - // nop // sll r0, r0, 0 - goto end_of_function; // return - - //jr ra // jr ra - c->daddu(sp, sp, r0); // daddu sp, sp, r0 - goto end_of_function; // return - - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - // nop // sll r0, r0, 0 - end_of_function: - return c->gprs[v0].du64[0]; -} - -void link() { - gLinkedFunctionTable.reg("cspace<-parented-transformq-joint!", execute, 128); -} - -} // namespace cspace<_parented_transformq_joint -} // namespace Mips2C -// add cspace<_parented_transformq_joint::link to the link callback table for the object file. -// FWD DEC: - - -namespace normalize_frame_quaternions { extern void link(); } - -namespace decompress_fixed_data_to_accumulator { extern void link(); } -namespace decompress_frame_data_to_accumulator { extern void link(); } - - -namespace decompress_frame_data_pair_to_accumulator { extern void link(); } diff --git a/game/mips2c/mips2c_table.cpp b/game/mips2c/mips2c_table.cpp index 0e643bbbc3..f9bb417c3f 100644 --- a/game/mips2c/mips2c_table.cpp +++ b/game/mips2c/mips2c_table.cpp @@ -68,9 +68,7 @@ namespace method_16_collide_edge_work { extern void link(); } namespace method_15_collide_edge_work { extern void link(); } namespace method_10_collide_edge_hold_list { extern void link(); } namespace method_18_collide_edge_work { extern void link(); } -namespace calc_animation_from_spr { extern void link(); } namespace bones_mtx_calc { extern void link(); } -namespace cspace_parented_transformq_joint { extern void link(); } namespace draw_bones_merc { extern void link(); } namespace draw_bones_check_longest_edge_asm { extern void link(); } namespace blerc_execute { extern void link(); } @@ -429,7 +427,6 @@ PerGameVersion>> gMips2C {"collide-edge-grab", {jak1::method_16_collide_edge_work::link, jak1::method_15_collide_edge_work::link, jak1::method_10_collide_edge_hold_list::link, jak1::method_18_collide_edge_work::link}}, - {"joint", {jak1::calc_animation_from_spr::link, jak1::cspace_parented_transformq_joint::link}}, {"bones", {jak1::bones_mtx_calc::link, jak1::draw_bones_merc::link, jak1::draw_bones_check_longest_edge_asm::link}}, diff --git a/goal_src/jak1/engine/anim/joint-ee-asm.gc b/goal_src/jak1/engine/anim/joint-ee-asm.gc new file mode 100644 index 0000000000..57327f44ad --- /dev/null +++ b/goal_src/jak1/engine/anim/joint-ee-asm.gc @@ -0,0 +1,2189 @@ +;; EE assembly / low level functions from the original game, unused in PC port. + +(defun flatten-joint-control-to-spr ((control joint-control)) + "Evaluate the controller's blend tree into 24 per-channel weights in spad, then fill in the + channel-upload-info list that the spad decompressor works from. A nonzero interp doubles + frame-qwc so the next frame comes across in the same DMA. The final weights are also copied to + inspector-amount for the debug display. + vf2 through vf14 keep physical names, because the blend and stack arms use them for unrelated + values." + (rlet ((weight-bcast :class vf) + (vf10 :class vf) + (vf11 :class vf) + (vf12 :class vf) + (vf13 :class vf) + (vf14 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + (vf8 :class vf) + (vf9 :class vf)) + (let ((channel-count (-> control active-channels))) + (let ((one 1.0) + (weight-offset 0) ;; this channel's float within a stack frame, bumped by 4 per channel + (frame-top (-> (scratchpad-object terrain-context) work foreground joint-work flattened))) + ;; A postfix blend tree. push starts an animation on a new stack frame, blend and push1 + ;; crossfade the top frame toward their channel, and stack combines and pops the top two. + ;; A stack frame is 24 weights, so six quads, and all six are scaled every time. + (dotimes (chan-idx channel-count) + (let ((chan (-> control channel chan-idx))) + (case (-> chan command) + (('push) + ;; Start with every channel at zero and this channel at one. + (let ((weight-slot (&+ (the-as pointer frame-top) weight-offset))) + (set! (-> frame-top 0 quad) (the-as uint128 0)) + (set! (-> frame-top 1 quad) (the-as uint128 0)) + (set! (-> frame-top 2 quad) (the-as uint128 0)) + (set! (-> frame-top 3 quad) (the-as uint128 0)) + (set! (-> frame-top 4 quad) (the-as uint128 0)) + (set! (-> frame-top 5 quad) (the-as uint128 0)) + ;; and this thing stores the normal weight. + (set! (-> (the-as (pointer float) weight-slot)) one)) + ;; advance. + (set! frame-top (the-as (inline-array vector) (-> frame-top 6)))) + (('blend 'push1) + (let ((new-weight (-> chan frame-interp))) + (let ((old-weight (- one new-weight))) (.mov weight-bcast old-weight)) + (let ((sf (the-as (inline-array vector) (-> frame-top -6)))) + (.lvf vf2 (&-> sf 0 quad)) + (let ((sf-weight-slot (&+ (the-as pointer sf) weight-offset))) + (.lvf vf3 (&-> sf 1 quad)) + (.lvf vf4 (&-> sf 2 quad)) + (.lvf vf5 (&-> sf 3 quad)) + (.lvf vf6 (&-> sf 4 quad)) + (.lvf vf7 (&-> sf 5 quad)) + (.mul.x.vf vf2 vf2 weight-bcast) + (.mul.x.vf vf3 vf3 weight-bcast) + (.mul.x.vf vf4 vf4 weight-bcast) + (.mul.x.vf vf5 vf5 weight-bcast) + (.mul.x.vf vf6 vf6 weight-bcast) + (.mul.x.vf vf7 vf7 weight-bcast) + (.svf (&-> sf 0 quad) vf2) + (.svf (&-> sf 1 quad) vf3) + (.svf (&-> sf 2 quad) vf4) + (.svf (&-> sf 3 quad) vf5) + (.svf (&-> sf 4 quad) vf6) + (.svf (&-> sf 5 quad) vf7) + (set! (-> (the-as (pointer float) sf-weight-slot)) (+ (-> (the-as (pointer float) sf-weight-slot) 0) new-weight))) + (set! frame-top (the-as (inline-array vector) (-> sf 6)))))) + (('stack) + (let* ((top-weight (-> chan frame-interp)) + (lower-weight (- one top-weight)) + (sf0 (the-as (inline-array vector) (-> frame-top -12)))) + (let ((top-w top-weight)) (.mov weight-bcast top-w)) + (let ((lower-w lower-weight)) (.mov vf2 lower-w)) + (.lvf vf3 (&-> sf0 0 quad)) + (.lvf vf4 (&-> sf0 1 quad)) + (.lvf vf5 (&-> sf0 2 quad)) + (.lvf vf6 (&-> sf0 3 quad)) + (.lvf vf7 (&-> sf0 4 quad)) + (.lvf vf8 (&-> sf0 5 quad)) + (.mul.x.vf vf3 vf3 vf2) + (.mul.x.vf vf4 vf4 vf2) + (.mul.x.vf vf5 vf5 vf2) + (.mul.x.vf vf6 vf6 vf2) + (.mul.x.vf vf7 vf7 vf2) + (.mul.x.vf vf8 vf8 vf2) + (.lvf vf9 (&-> sf0 6 quad)) + (.lvf vf10 (&-> sf0 7 quad)) + (.lvf vf11 (&-> sf0 8 quad)) + (.lvf vf12 (&-> sf0 9 quad)) + (.lvf vf13 (&-> sf0 10 quad)) + (.lvf vf14 (&-> sf0 11 quad)) + (.mul.x.vf vf9 vf9 weight-bcast) + (.mul.x.vf vf10 vf10 weight-bcast) + (.mul.x.vf vf11 vf11 weight-bcast) + (.mul.x.vf vf12 vf12 weight-bcast) + (.mul.x.vf vf13 vf13 weight-bcast) + (.mul.x.vf vf14 vf14 weight-bcast) + (.add.vf vf3 vf3 vf9) + (.add.vf vf4 vf4 vf10) + (.add.vf vf5 vf5 vf11) + (.add.vf vf6 vf6 vf12) + (.add.vf vf7 vf7 vf13) + (.add.vf vf8 vf8 vf14) + (.svf (&-> sf0 0 quad) vf3) + (.svf (&-> sf0 1 quad) vf4) + (.svf (&-> sf0 2 quad) vf5) + (.svf (&-> sf0 3 quad) vf6) + (.svf (&-> sf0 4 quad) vf7) + (.svf (&-> sf0 5 quad) vf8) + (set! frame-top (the-as (inline-array vector) (-> sf0 6))))))) + (+! weight-offset 4))) + (let ((upload-index 0)) + (dotimes (channel-index channel-count) + (when (< 0.001 (-> (scratchpad-object terrain-context) work foreground joint-work flatten-array channel-index)) + (let* ((chan (-> control channel channel-index)) + (jacc (-> chan frame-group frames)) + (frame-num (-> chan frame-num)) + (base-frame (the int frame-num)) + (frac-frame (- frame-num (the float base-frame)))) + (let ((last-frame (+ (-> jacc num-frames) -1))) + (if (not (-> chan frame-group)) (format 0 "Channel ~D skel ~A frame-group is #f!!!~%" channel-index control)) + (when (>= base-frame (the-as int last-frame)) + (set! frac-frame 0.0) + (set! base-frame (the-as int last-frame)))) + (let ((up (-> (scratchpad-object terrain-context) work foreground joint-work uploads upload-index))) + (set! (-> up fixed) (-> jacc fixed)) + (set! (-> up fixed-qwc) (the-as int (-> jacc fixed-qwc))) + (set! (-> up frame) (-> jacc data base-frame)) + (set! (-> up frame-qwc) (the-as int (if (= frac-frame 0.0) (-> jacc frame-qwc) (* (-> jacc frame-qwc) 2)))) + (set! (-> up amount) (-> (scratchpad-object terrain-context) work foreground joint-work flatten-array channel-index)) + (set! (-> up interp) frac-frame))) + (+! upload-index 1))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work num-uploads) upload-index)) + (dotimes (i channel-count) + (set! (-> control channel i inspector-amount) + (-> (scratchpad-object terrain-context) work foreground joint-work flatten-array i)))) + 0)) + + +(#unless PC_PORT + (defun clear-frame-accumulator ((destination (inline-array vector))) + "Zero the two matrices and every transformq after them. The joint count arrives in s2 from + calc-animation-from-spr, and the -2 accounts for those two matrices." + (rlet ((cursor destination) + (remaining :reg s2) + (zero :class i128)) + (s.q zero cursor) + (-! remaining 2) + (s.q zero cursor 16) + (nop!) + (s.q zero cursor 32) + (nop!) + (s.q zero cursor 48) + (nop!) + (s.q zero cursor 64) + (nop!) + (s.q zero cursor 80) + (nop!) + (s.q zero cursor 96) + (nop!) + (s.q zero cursor 112) + (&+! cursor 128) + (label clear-transform) + (s.q zero cursor) + (-! remaining 1) + (s.q zero cursor 16) + (&+! cursor 48) + (nop!) + (nop!) + (b.nz remaining clear-transform :delay (s.q zero cursor -16)))) + (defun normalize-frame-quaternions ((destination (inline-array vector))) + "Set trans.w and scale.w back to 1.0 and renormalize every accumulated quaternion. The joint + count is in s2, less the two matrices." + (rlet ((cursor (&+ destination 128)) + (remaining :reg s2) + (translation :reg vf1) + (rotation :reg vf4) + (scale :reg vf7) + (squared :reg vf10)) + (-! remaining 2) + (label normalize-transform) + (l.vf rotation cursor 16) + (l.vf translation cursor) + (l.vf scale cursor 32) + (mul.vf squared rotation rotation) + (move.w.vf translation vf0) + (move.w.vf scale vf0) + (mula.w.vf vf0 squared) + (madda.z.vf vf0 squared) + (madda.y.vf vf0 squared) + (madd.x.vf squared vf0 squared) + (s.vf translation cursor) + (s.vf scale cursor 32) + (&+! cursor 48) + (rsqrt.w.w Q vf0 squared) + (waitq) + (mulq.vf rotation rotation Q) + (-! remaining 1) + (b.nz remaining normalize-transform :delay (s.vf rotation cursor -32)))) + (defun decompress-fixed-data-to-accumulator () + "Add an animation's fixed components to the frame accumulator, weighted. The 64-byte header is + copied to spad first because the control nibbles are read many times, then either fixed matrix, + then one computed jump per transform record." + (declare (asm-func)) + ;; The three decompressors share one private register ABI set up by calc-animation-from-spr, + ;; so these are pinned rather than allocated. frame walks the output accumulator, block is the + ;; compressed source in spad, weight is the blend amount, and hdr is the spad copy of the + ;; fixed block's header. stream64, stream32 and stream16 are the three read cursors. + ;; transforms-left counts down the post-matrix records, controls holds the current packed + ;; control word with nibbles-left nibbles still in it, and control-ptr walks the rest. + ;; vf1 through vf12 carry two names each: matrix rows in the header section, then translation, + ;; quaternion and scale in the per-transform paths. They are the same registers either way. + (rlet ((frame :reg a0) + (block :reg a1 :type joint-anim-compressed-fixed) + (weight :reg a2) + (hdr :reg t1 :type joint-anim-compressed-hdr) + (jump-table :reg t2) + (nibble :reg t3) + (stream64 :reg t4) + (stream32 :reg t5) + (stream16 :reg t6) + (hdr-qw-a :reg t4) ;; borrowed as quadword shuttles for the header copy + (hdr-qw-b :reg t5) + (transforms-left :reg s2) + (nibbles-left :reg s3) + (controls :reg s4) + (control-ptr :reg s5) + (data-base :reg v1) + (pack :reg s6) + (pack-hi :reg gp) + (pack2 :reg t8) + (pack2-hi :reg fp) + (xfer :reg t9) + (mtx-row0 :reg vf1) + (mtx-row1 :reg vf2) + (mtx-row2 :reg vf3) + (mtx-row3 :reg vf4) + (acc-row0 :reg vf9) + (acc-row1 :reg vf10) + (acc-row2 :reg vf11) + (acc-row3 :reg vf12) + (trans :reg vf1) + (trans-b :reg vf2) + (out-trans :reg vf3) + (quat :reg vf4) + (quat-b :reg vf5) + (out-quat :reg vf6) + (scale :reg vf7) + (scale-b :reg vf8) + (out-scale :reg vf9) + (dot :reg vf10) + (weight-vf :reg vf13) + (scales :reg vf14) + (zero-vf :reg vf15)) + (label fixed-entry) + (l.q hdr-qw-a block) + (add.i sp sp -16) + (l.q hdr-qw-b block 16) + (nop!) + (s.q hdr-qw-a hdr) + (nop!) + (s.q hdr-qw-b hdr 16) + (nop!) + (l.q hdr-qw-a block 32) + (nop!) + (l.q hdr-qw-b block 48) + (nop!) + (s.q hdr-qw-a hdr 32) + (nop!) + (s.q hdr-qw-b hdr 48) + (nop!) + (s.q frame sp) + (nop!) + (m weight-vf weight) + (lui jump-table 28672) ;; spad base, 0x70000000 + (l.w stream64 (-> block offset-64)) + (add.i data-base block (offset-of joint-anim-compressed-fixed data)) + (l.w stream32 (-> block offset-32)) + (add control-ptr hdr r0) + (l.w stream16 (-> block offset-16)) + (add stream64 stream64 data-base) + (mul.x.vf weight-vf scales weight-vf) + (add.i jump-table jump-table (joint-spad-offset fix-jmp-table)) + (l.w transforms-left (-> hdr num-joints)) + (add stream32 stream32 data-base) + (l.w controls (-> hdr matrix-bits)) + (add stream16 stream16 data-base) + (add.i nibbles-left r0 8) + (add.i control-ptr control-ptr 4) + (and.i nibble controls 1) + (nop!) + (b.nz nibble fixed-second-matrix :delay (nop!)) + (l.vf mtx-row0 stream64) + (l.vf mtx-row1 stream64 16) + (l.vf mtx-row2 stream64 32) + (l.vf mtx-row3 stream64 48) + (l.vf acc-row0 frame) + (add.i stream64 stream64 64) + (l.vf acc-row1 frame 16) + (nop!) + (l.vf acc-row2 frame 32) + (l.vf acc-row3 frame 48) + (mula.w.vf acc-row0 vf0) + (madd.x.vf acc-row0 mtx-row0 weight-vf) + (mula.w.vf acc-row1 vf0) + (madd.x.vf acc-row1 mtx-row1 weight-vf) + (mula.w.vf acc-row2 vf0) + (madd.x.vf acc-row2 mtx-row2 weight-vf) + (mula.w.vf acc-row3 vf0) + (madd.x.vf acc-row3 mtx-row3 weight-vf) + (s.vf acc-row0 frame) + (s.vf acc-row1 frame 16) + (s.vf acc-row2 frame 32) + (s.vf acc-row3 frame 48) + (label fixed-second-matrix) + (and.i nibble controls 2) + (add.i frame frame 64) + (b.nz nibble fixed-controls :delay (nop!)) + (l.vf mtx-row0 stream64) + (l.vf mtx-row1 stream64 16) + (l.vf mtx-row2 stream64 32) + (l.vf mtx-row3 stream64 48) + (l.vf acc-row0 frame) + (add.i stream64 stream64 64) + (l.vf acc-row1 frame 16) + (nop!) + (l.vf acc-row2 frame 32) + (l.vf acc-row3 frame 48) + (mula.w.vf acc-row0 vf0) + (madd.x.vf acc-row0 mtx-row0 weight-vf) + (mula.w.vf acc-row1 vf0) + (madd.x.vf acc-row1 mtx-row1 weight-vf) + (mula.w.vf acc-row2 vf0) + (madd.x.vf acc-row2 mtx-row2 weight-vf) + (mula.w.vf acc-row3 vf0) + (madd.x.vf acc-row3 mtx-row3 weight-vf) + (s.vf acc-row0 frame) + (s.vf acc-row1 frame 16) + (s.vf acc-row2 frame 32) + (s.vf acc-row3 frame 48) + (label fixed-controls) + (l.w controls control-ptr -4) + (add.i frame frame 64) + (label fixed-dispatch) + (and.i nibble controls 15) + (sra controls controls 4) + (sll nibble nibble 2) + (add.i nibbles-left nibbles-left -1) + (add nibble nibble jump-table) + (add.i transforms-left transforms-left -1) + (l.w nibble nibble) + (nop!) + (nop!) + (nop!) + (jr nibble :delay (nop!)) + (label fixed-next-transform) + (b.z transforms-left fixed-return :delay (add.i frame frame 48)) + (b.nz nibbles-left fixed-dispatch :delay (nop!)) + (l.w controls control-ptr) + (add.i control-ptr control-ptr 4) + (b fixed-dispatch :delay (add.i nibbles-left r0 8)) + ;; control nibble 0: the clear bits, so these components come from the fixed streams + (label fixed-path-trans-quat-scale) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (itof.vf quat quat :fixed 15) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (mul.vf dot quat out-quat) + (m trans pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (itof.vf trans trans) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (m xfer dot) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 fixed-quaternion-ready-0 :delay (sub.vf quat zero-vf quat)) + (label fixed-quaternion-ready-0) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (mula.w.vf out-trans vf0) + (madd.y.vf out-trans trans weight-vf) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (s.vf out-scale frame 32) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 8: the clear bits, so these components come from the fixed streams + (label fixed-path-wide-trans-quat-scale) + (l.d xfer stream64 8) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d pack stream64 -8) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (itof.vf quat quat :fixed 15) + (pcpyld pack pack-hi pack) + (mul.vf dot quat out-quat) + (m trans pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (m xfer dot) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 fixed-quaternion-ready-1 :delay (sub.vf quat zero-vf quat)) + (label fixed-quaternion-ready-1) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (mula.w.vf out-trans vf0) + (madd.x.vf out-trans trans weight-vf) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (s.vf out-scale frame 32) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 1, 9: the clear bits, so these components come from the fixed streams + (label fixed-path-quat-scale) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (itof.vf quat quat :fixed 15) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (mul.vf dot quat out-quat) + (m scale pack2) + (mula.w.vf dot vf0) + (itof.vf scale scale :fixed 12) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (m xfer dot) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 fixed-quaternion-ready-2 :delay (sub.vf quat zero-vf quat)) + (label fixed-quaternion-ready-2) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (s.vf out-quat frame 16) + (s.vf out-scale frame 32) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 2: the clear bits, so these components come from the fixed streams + (label fixed-path-trans-scale) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (itof.vf trans trans) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (mula.w.vf out-trans vf0) + (madd.y.vf out-trans trans weight-vf) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-trans frame) + (s.vf out-scale frame 32) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 10: the clear bits, so these components come from the fixed streams + (label fixed-path-wide-trans-scale) + (l.d pack stream64) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (pcpyld pack pack-hi pack) + (m trans pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (mula.w.vf out-trans vf0) + (madd.x.vf out-trans trans weight-vf) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-trans frame) + (s.vf out-scale frame 32) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 3, 11: the clear bits, so these components come from the fixed streams + (label fixed-path-scale) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-scale frame 32) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 4: the clear bits, so these components come from the fixed streams + (label fixed-path-trans-quat) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (itof.vf quat quat :fixed 15) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (mul.vf dot quat out-quat) + (m trans pack) + (mula.w.vf dot vf0) + (itof.vf trans trans) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (mula.w.vf out-trans vf0) + (madd.y.vf out-trans trans weight-vf) + (m xfer dot) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 fixed-quaternion-ready-3 :delay (sub.vf quat zero-vf quat)) + (label fixed-quaternion-ready-3) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 12: the clear bits, so these components come from the fixed streams + (label fixed-path-wide-trans-quat) + (l.d xfer stream64 8) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d pack stream64 -8) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (itof.vf quat quat :fixed 15) + (pcpyld pack pack-hi pack) + (mul.vf dot quat out-quat) + (m trans pack) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (mula.w.vf out-trans vf0) + (madd.x.vf out-trans trans weight-vf) + (m xfer dot) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 fixed-quaternion-ready-4 :delay (sub.vf quat zero-vf quat)) + (label fixed-quaternion-ready-4) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 5, 13: the clear bits, so these components come from the fixed streams + (label fixed-path-quat) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (itof.vf quat quat :fixed 15) + (mul.vf dot quat out-quat) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (m xfer dot) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 fixed-quaternion-ready-5 :delay (sub.vf quat zero-vf quat)) + (label fixed-quaternion-ready-5) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (s.vf out-quat frame 16) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 6: the clear bits, so these components come from the fixed streams + (label fixed-path-trans) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans pack) + (itof.vf trans trans) + (mula.w.vf out-trans vf0) + (madd.y.vf out-trans trans weight-vf) + (s.vf out-trans frame) + (b fixed-next-transform :delay (nop!)) + ;; control nibble 14: the clear bits, so these components come from the fixed streams + (label fixed-path-wide-trans) + (l.d pack stream64) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (pcpyld pack pack-hi pack) + (m trans pack) + (mula.w.vf out-trans vf0) + (madd.x.vf out-trans trans weight-vf) + (s.vf out-trans frame) + (b fixed-next-transform :delay (nop!)) + (label fixed-return) + (l.q frame sp) + (nop!) + (jr ra :delay (add.i sp sp 16)) + (jr ra :delay (add sp sp r0)) + (nop!) + (nop!) + (nop!))) + (defun decompress-frame-data-to-accumulator () + "Same as decompress-fixed-data-to-accumulator, but for one frame's animated components, so the + control-bit tests are inverted. The header is already in spad from the fixed pass." + (declare (asm-func)) + ;; The three decompressors share one private register ABI set up by calc-animation-from-spr, + ;; so these are pinned rather than allocated. frame walks the output accumulator, block is the + ;; compressed source in spad, weight is the blend amount, and hdr is the spad copy of the + ;; fixed block's header. stream64, stream32 and stream16 are the three read cursors. + ;; transforms-left counts down the post-matrix records, controls holds the current packed + ;; control word with nibbles-left nibbles still in it, and control-ptr walks the rest. + ;; vf1 through vf12 carry two names each: matrix rows in the header section, then translation, + ;; quaternion and scale in the per-transform paths. They are the same registers either way. + (rlet ((frame :reg a0) + (block :reg a1 :type joint-anim-compressed-frame) + (weight :reg a2) + (hdr :reg t1 :type joint-anim-compressed-hdr) + (jump-table :reg t2) + (nibble :reg t3) + (stream64 :reg t4) + (stream32 :reg t5) + (stream16 :reg t6) + (transforms-left :reg s2) + (nibbles-left :reg s3) + (controls :reg s4) + (control-ptr :reg s5) + (data-base :reg v1) + (pack :reg s6) + (pack-hi :reg gp) + (pack2 :reg t8) + (pack2-hi :reg fp) + (xfer :reg t9) + (mtx-row0 :reg vf1) + (mtx-row1 :reg vf2) + (mtx-row2 :reg vf3) + (mtx-row3 :reg vf4) + (acc-row0 :reg vf9) + (acc-row1 :reg vf10) + (acc-row2 :reg vf11) + (acc-row3 :reg vf12) + (trans :reg vf1) + (trans-b :reg vf2) + (out-trans :reg vf3) + (quat :reg vf4) + (quat-b :reg vf5) + (out-quat :reg vf6) + (scale :reg vf7) + (scale-b :reg vf8) + (out-scale :reg vf9) + (dot :reg vf10) + (weight-vf :reg vf13) + (scales :reg vf14) + (zero-vf :reg vf15)) + (label frame-entry) + (add.i sp sp -16) + (m weight-vf weight) + (s.q frame sp) + (lui jump-table 28672) ;; spad base, 0x70000000 + (l.w stream64 (-> block offset-64)) + (add.i data-base block (offset-of joint-anim-compressed-frame data)) + (l.w stream32 (-> block offset-32)) + (add control-ptr hdr r0) + (l.w stream16 (-> block offset-16)) + (add stream64 stream64 data-base) + (mul.x.vf weight-vf scales weight-vf) + (add.i jump-table jump-table (joint-spad-offset frm-jmp-table)) + (l.w transforms-left (-> hdr num-joints)) + (add stream32 stream32 data-base) + (l.w controls (-> hdr matrix-bits)) + (add stream16 stream16 data-base) + (add.i nibbles-left r0 8) + (add.i control-ptr control-ptr 4) + (and.i nibble controls 1) + (nop!) + (b.z nibble frame-second-matrix :delay (nop!)) + (l.vf mtx-row0 stream64) + (l.vf mtx-row1 stream64 16) + (l.vf mtx-row2 stream64 32) + (l.vf mtx-row3 stream64 48) + (l.vf acc-row0 frame) + (add.i stream64 stream64 64) + (l.vf acc-row1 frame 16) + (nop!) + (l.vf acc-row2 frame 32) + (l.vf acc-row3 frame 48) + (mula.w.vf acc-row0 vf0) + (madd.x.vf acc-row0 mtx-row0 weight-vf) + (mula.w.vf acc-row1 vf0) + (madd.x.vf acc-row1 mtx-row1 weight-vf) + (mula.w.vf acc-row2 vf0) + (madd.x.vf acc-row2 mtx-row2 weight-vf) + (mula.w.vf acc-row3 vf0) + (madd.x.vf acc-row3 mtx-row3 weight-vf) + (s.vf acc-row0 frame) + (s.vf acc-row1 frame 16) + (s.vf acc-row2 frame 32) + (s.vf acc-row3 frame 48) + (label frame-second-matrix) + (and.i nibble controls 2) + (add.i frame frame 64) + (b.z nibble frame-controls :delay (nop!)) + (l.vf mtx-row0 stream64) + (l.vf mtx-row1 stream64 16) + (l.vf mtx-row2 stream64 32) + (l.vf mtx-row3 stream64 48) + (l.vf acc-row0 frame) + (add.i stream64 stream64 64) + (l.vf acc-row1 frame 16) + (nop!) + (l.vf acc-row2 frame 32) + (l.vf acc-row3 frame 48) + (mula.w.vf acc-row0 vf0) + (madd.x.vf acc-row0 mtx-row0 weight-vf) + (mula.w.vf acc-row1 vf0) + (madd.x.vf acc-row1 mtx-row1 weight-vf) + (mula.w.vf acc-row2 vf0) + (madd.x.vf acc-row2 mtx-row2 weight-vf) + (mula.w.vf acc-row3 vf0) + (madd.x.vf acc-row3 mtx-row3 weight-vf) + (s.vf acc-row0 frame) + (s.vf acc-row1 frame 16) + (s.vf acc-row2 frame 32) + (s.vf acc-row3 frame 48) + (label frame-controls) + (l.w controls control-ptr -4) + (add.i frame frame 64) + (label frame-dispatch) + (and.i nibble controls 15) + (sra controls controls 4) + (sll nibble nibble 2) + (add.i nibbles-left nibbles-left -1) + (add nibble nibble jump-table) + (add.i transforms-left transforms-left -1) + (l.w nibble nibble) + (nop!) + (nop!) + (nop!) + (jr nibble :delay (nop!)) + (label frame-next-transform) + (b.z transforms-left frame-return :delay (add.i frame frame 48)) + (b.nz nibbles-left frame-dispatch :delay (nop!)) + (l.w controls control-ptr) + (add.i control-ptr control-ptr 4) + (b frame-dispatch :delay (add.i nibbles-left r0 8)) + ;; control nibble 1: the set bits, so these components come from this frame + (label frame-path-trans) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans pack) + (itof.vf trans trans) + (mula.w.vf out-trans vf0) + (madd.y.vf out-trans trans weight-vf) + (s.vf out-trans frame) + (b frame-next-transform :delay (nop!)) + ;; control nibble 9: the set bits, so these components come from this frame + (label frame-path-wide-trans) + (l.d pack stream64) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (pcpyld pack pack-hi pack) + (m trans pack) + (mula.w.vf out-trans vf0) + (madd.x.vf out-trans trans weight-vf) + (s.vf out-trans frame) + (b frame-next-transform :delay (nop!)) + ;; control nibble 2, 10: the set bits, so these components come from this frame + (label frame-path-quat) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (itof.vf quat quat :fixed 15) + (mul.vf dot quat out-quat) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (m xfer dot) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 frame-quaternion-ready-0 :delay (sub.vf quat zero-vf quat)) + (label frame-quaternion-ready-0) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (s.vf out-quat frame 16) + (b frame-next-transform :delay (nop!)) + ;; control nibble 3: the set bits, so these components come from this frame + (label frame-path-quat-trans) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (itof.vf quat quat :fixed 15) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (mul.vf dot quat out-quat) + (m trans pack) + (mula.w.vf dot vf0) + (itof.vf trans trans) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (mula.w.vf out-trans vf0) + (madd.y.vf out-trans trans weight-vf) + (m xfer dot) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 frame-quaternion-ready-1 :delay (sub.vf quat zero-vf quat)) + (label frame-quaternion-ready-1) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (b frame-next-transform :delay (nop!)) + ;; control nibble 11: the set bits, so these components come from this frame + (label frame-path-quat-wide-trans) + (l.d xfer stream64 8) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d pack stream64 -8) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (itof.vf quat quat :fixed 15) + (pcpyld pack pack-hi pack) + (mul.vf dot quat out-quat) + (m trans pack) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (mula.w.vf out-trans vf0) + (madd.x.vf out-trans trans weight-vf) + (m xfer dot) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 frame-quaternion-ready-2 :delay (sub.vf quat zero-vf quat)) + (label frame-quaternion-ready-2) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (b frame-next-transform :delay (nop!)) + ;; control nibble 4, 12: the set bits, so these components come from this frame + (label frame-path-scale) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-scale frame 32) + (b frame-next-transform :delay (nop!)) + ;; control nibble 5: the set bits, so these components come from this frame + (label frame-path-trans-scale) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (itof.vf trans trans) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (mula.w.vf out-trans vf0) + (madd.y.vf out-trans trans weight-vf) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-trans frame) + (s.vf out-scale frame 32) + (b frame-next-transform :delay (nop!)) + ;; control nibble 13: the set bits, so these components come from this frame + (label frame-path-wide-trans-scale) + (l.d pack stream64) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (pcpyld pack pack-hi pack) + (m trans pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (mula.w.vf out-trans vf0) + (madd.x.vf out-trans trans weight-vf) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-trans frame) + (s.vf out-scale frame 32) + (b frame-next-transform :delay (nop!)) + ;; control nibble 6, 14: the set bits, so these components come from this frame + (label frame-path-quat-scale) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (itof.vf quat quat :fixed 15) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (mul.vf dot quat out-quat) + (m scale pack2) + (mula.w.vf dot vf0) + (itof.vf scale scale :fixed 12) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (m xfer dot) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 frame-quaternion-ready-3 :delay (sub.vf quat zero-vf quat)) + (label frame-quaternion-ready-3) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (s.vf out-quat frame 16) + (s.vf out-scale frame 32) + (b frame-next-transform :delay (nop!)) + ;; control nibble 7: the set bits, so these components come from this frame + (label frame-path-quat-trans-scale) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (itof.vf quat quat :fixed 15) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (mul.vf dot quat out-quat) + (m trans pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (itof.vf trans trans) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (m xfer dot) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 frame-quaternion-ready-4 :delay (sub.vf quat zero-vf quat)) + (label frame-quaternion-ready-4) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (mula.w.vf out-trans vf0) + (madd.y.vf out-trans trans weight-vf) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (s.vf out-scale frame 32) + (b frame-next-transform :delay (nop!)) + ;; control nibble 15: the set bits, so these components come from this frame + (label frame-path-quat-wide-trans-scale) + (l.d xfer stream64 8) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d pack stream64 -8) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (itof.vf quat quat :fixed 15) + (pcpyld pack pack-hi pack) + (mul.vf dot quat out-quat) + (m trans pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (m xfer dot) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 frame-quaternion-ready-5 :delay (sub.vf quat zero-vf quat)) + (label frame-quaternion-ready-5) + (itof.vf scale scale :fixed 12) + (mula.w.vf out-quat vf0) + (madd.x.vf out-quat quat weight-vf) + (mula.w.vf out-trans vf0) + (madd.x.vf out-trans trans weight-vf) + (mula.w.vf out-scale vf0) + (madd.x.vf out-scale scale weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (s.vf out-scale frame 32) + (b frame-next-transform :delay (nop!)) + (label frame-return) + (l.q frame sp) + (nop!) + (jr ra :delay (add.i sp sp 16)) + (jr ra :delay (add sp sp r0)) + (nop!) + (nop!) + (nop!))) + (defun decompress-frame-data-pair-to-accumulator () + "Decode two adjacent frames at once. Every present component is read from both, blended with + interp and 1 - interp, and added once. After the setup weight-vf carries both halves, x and w + holding the pair weights and y and z the compact-translation factor. Only the first frame's + quaternion is hemisphere-checked; the second rides along with it." + (declare (asm-func)) + ;; The three decompressors share one private register ABI set up by calc-animation-from-spr, + ;; so these are pinned rather than allocated. frame walks the output accumulator, block is the + ;; compressed source in spad, weight is the blend amount, and hdr is the spad copy of the + ;; fixed block's header. stream64, stream32 and stream16 are the three read cursors. + ;; transforms-left counts down the post-matrix records, controls holds the current packed + ;; control word with nibbles-left nibbles still in it, and control-ptr walks the rest. + ;; vf1 through vf12 carry two names each: matrix rows in the header section, then translation, + ;; quaternion and scale in the per-transform paths. They are the same registers either way. + (rlet ((frame :reg a0) + (block :reg a1 :type joint-anim-compressed-frame) + (weight :reg a2) + (second-block :reg a3 :type joint-anim-compressed-frame) + (interp :reg t0) + (hdr :reg t1 :type joint-anim-compressed-hdr) + (jump-table :reg t2) + (nibble :reg t3) + (stream64 :reg t4) + (stream32 :reg t5) + (stream16 :reg t6) + (stream64-b :reg t7) + (stream32-b :reg s0) + (stream16-b :reg s1) + (transforms-left :reg s2) + (nibbles-left :reg s3) + (controls :reg s4) + (control-ptr :reg s5) + (data-base :reg v1) + (pack :reg s6) + (pack-hi :reg gp) + (pack2 :reg t8) + (pack2-hi :reg fp) + (xfer :reg t9) + (mtx-row0 :reg vf1) + (mtx-row1 :reg vf2) + (mtx-row2 :reg vf3) + (mtx-row3 :reg vf4) + (acc-row0 :reg vf9) + (acc-row1 :reg vf10) + (acc-row2 :reg vf11) + (acc-row3 :reg vf12) + (trans :reg vf1) + (trans-b :reg vf2) + (out-trans :reg vf3) + (quat :reg vf4) + (quat-b :reg vf5) + (out-quat :reg vf6) + (scale :reg vf7) + (scale-b :reg vf8) + (out-scale :reg vf9) + (dot :reg vf10) + (mtx2-row0 :reg vf5) + (mtx2-row1 :reg vf6) + (mtx2-row2 :reg vf7) + (mtx2-row3 :reg vf8) + (interp-vf :reg vf11) + (weight-vf :reg vf13) + (scales :reg vf14) + (zero-vf :reg vf15)) + (label pair-entry) + (add.i sp sp -64) + (s.q frame sp) + (s.q stream64-b sp 16) + (s.q stream32-b sp 32) + (s.q stream16-b sp 48) + (m interp-vf interp) + (add second-block second-block block) + (m weight-vf weight) + (lui jump-table 28672) ;; spad base, 0x70000000 + (l.w stream64 (-> block offset-64)) + (add.i data-base block (offset-of joint-anim-compressed-frame data)) + (l.w stream32 (-> block offset-32)) + (add control-ptr hdr r0) + (l.w stream16 (-> block offset-16)) + (add stream64 stream64 data-base) + (sub.x.vf.w interp-vf vf0 interp-vf) + (l.w stream64-b (-> second-block offset-64)) + (mul.x.vf weight-vf scales weight-vf) + (add.i jump-table jump-table (joint-spad-offset pair-jmp-table)) + (l.w transforms-left (-> hdr num-joints)) + (add stream32 stream32 data-base) + (l.w controls (-> hdr matrix-bits)) + (add stream16 stream16 data-base) + (add.i nibbles-left r0 8) + (add.i control-ptr control-ptr 4) + (mul.w.vf.xy weight-vf weight-vf interp-vf) + (l.w stream32-b (-> second-block offset-32)) + (mul.x.vf.zw weight-vf weight-vf interp-vf) + (l.w stream16-b (-> second-block offset-16)) + (nop!) + (add.i data-base second-block (offset-of joint-anim-compressed-frame data)) + (add stream64-b stream64-b data-base) + (add stream32-b stream32-b data-base) + (add stream16-b stream16-b data-base) + (nop!) + (and.i nibble controls 1) + (nop!) + (b.z nibble pair-second-matrix :delay (nop!)) + (l.vf mtx-row0 stream64) + (l.vf mtx-row1 stream64 16) + (l.vf mtx-row2 stream64 32) + (l.vf mtx-row3 stream64 48) + (l.vf mtx2-row0 stream64-b) + (l.vf mtx2-row1 stream64-b 16) + (l.vf mtx2-row2 stream64-b 32) + (l.vf mtx2-row3 stream64-b 48) + (l.vf acc-row0 frame) + (add.i stream64 stream64 64) + (l.vf acc-row1 frame 16) + (add.i stream64-b stream64-b 64) + (l.vf interp-vf frame 32) + (l.vf acc-row3 frame 48) + (mula.w.vf acc-row0 vf0) + (madda.x.vf mtx-row0 weight-vf) + (madd.w.vf acc-row0 mtx2-row0 weight-vf) + (mula.w.vf acc-row1 vf0) + (madda.x.vf mtx-row1 weight-vf) + (madd.w.vf acc-row1 mtx2-row1 weight-vf) + (mula.w.vf interp-vf vf0) + (madda.x.vf mtx-row2 weight-vf) + (madd.w.vf interp-vf mtx2-row2 weight-vf) + (mula.w.vf acc-row3 vf0) + (madda.x.vf mtx-row3 weight-vf) + (madd.w.vf acc-row3 mtx2-row3 weight-vf) + (s.vf acc-row0 frame) + (s.vf acc-row1 frame 16) + (s.vf interp-vf frame 32) + (s.vf acc-row3 frame 48) + (label pair-second-matrix) + (and.i nibble controls 2) + (add.i frame frame 64) + (b.z nibble pair-controls :delay (nop!)) + (l.vf mtx-row0 stream64) + (l.vf mtx-row1 stream64 16) + (l.vf mtx-row2 stream64 32) + (l.vf mtx-row3 stream64 48) + (l.vf mtx2-row0 stream64-b) + (l.vf mtx2-row1 stream64-b 16) + (l.vf mtx2-row2 stream64-b 32) + (l.vf mtx2-row3 stream64-b 48) + (l.vf acc-row0 frame) + (add.i stream64 stream64 64) + (l.vf acc-row1 frame 16) + (add.i stream64-b stream64-b 64) + (l.vf interp-vf frame 32) + (l.vf acc-row3 frame 48) + (mula.w.vf acc-row0 vf0) + (madda.x.vf mtx-row0 weight-vf) + (madd.w.vf acc-row0 mtx2-row0 weight-vf) + (mula.w.vf acc-row1 vf0) + (madda.x.vf mtx-row1 weight-vf) + (madd.w.vf acc-row1 mtx2-row1 weight-vf) + (mula.w.vf interp-vf vf0) + (madda.x.vf mtx-row2 weight-vf) + (madd.w.vf interp-vf mtx2-row2 weight-vf) + (mula.w.vf acc-row3 vf0) + (madda.x.vf mtx-row3 weight-vf) + (madd.w.vf acc-row3 mtx2-row3 weight-vf) + (s.vf acc-row0 frame) + (s.vf acc-row1 frame 16) + (s.vf interp-vf frame 32) + (s.vf acc-row3 frame 48) + (label pair-controls) + (l.w controls control-ptr -4) + (add.i frame frame 64) + (label pair-dispatch) + (and.i nibble controls 15) + (sra controls controls 4) + (sll nibble nibble 2) + (add.i nibbles-left nibbles-left -1) + (add nibble nibble jump-table) + (add.i transforms-left transforms-left -1) + (l.w nibble nibble) + (nop!) + (nop!) + (nop!) + (jr nibble :delay (nop!)) + (label pair-next-transform) + (b.z transforms-left pair-return :delay (add.i frame frame 48)) + (b.nz nibbles-left pair-dispatch :delay (nop!)) + (l.w controls control-ptr) + (add.i control-ptr control-ptr 4) + (b pair-dispatch :delay (add.i nibbles-left r0 8)) + ;; control nibble 1: the set bits, decoded from both frames and blended + (label pair-path-trans) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans pack) + (l.w pack stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack-hi stream16-b) + (add.i stream16-b stream16-b 2) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans-b pack) + (itof.vf trans trans) + (itof.vf trans-b trans-b) + (mula.w.vf out-trans vf0) + (madda.y.vf trans weight-vf) + (madd.z.vf out-trans trans-b weight-vf) + (s.vf out-trans frame) + (b pair-next-transform :delay (nop!)) + ;; control nibble 9: the set bits, decoded from both frames and blended + (label pair-path-wide-trans) + (l.d pack stream64) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (pcpyld pack pack-hi pack) + (m trans pack) + (l.d pack stream64-b) + (add.i stream64-b stream64-b 8) + (l.w pack-hi stream32-b) + (add.i stream32-b stream32-b 4) + (pcpyld pack pack-hi pack) + (m trans-b pack) + (mula.w.vf out-trans vf0) + (madda.x.vf trans weight-vf) + (madd.w.vf out-trans trans-b weight-vf) + (s.vf out-trans frame) + (b pair-next-transform :delay (nop!)) + ;; control nibble 2, 10: the set bits, decoded from both frames and blended + (label pair-path-quat) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d xfer stream64-b) + (add.i stream64-b stream64-b 8) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat-b xfer) + (itof.vf quat quat :fixed 15) + (itof.vf quat-b quat-b :fixed 15) + (mula.x.vf quat weight-vf) + (madd.w.vf quat quat-b weight-vf) + (mul.vf dot quat out-quat) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (m xfer dot) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 pair-quaternion-ready-0 :delay (sub.vf quat zero-vf quat)) + (label pair-quaternion-ready-0) + (add.vf out-quat out-quat quat) + (s.vf out-quat frame 16) + (b pair-next-transform :delay (nop!)) + ;; control nibble 3: the set bits, decoded from both frames and blended + (label pair-path-quat-trans) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d xfer stream64-b) + (add.i stream64-b stream64-b 8) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat-b xfer) + (itof.vf quat quat :fixed 15) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (itof.vf quat-b quat-b :fixed 15) + (l.vf out-trans frame) + (pextlw pack pack-hi pack) + (mula.x.vf quat weight-vf) + (madd.w.vf quat quat-b weight-vf) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans pack) + (mul.vf dot quat out-quat) + (l.w pack stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack-hi stream16-b) + (add.i stream16-b stream16-b 2) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m xfer dot) + (m trans-b pack) + (itof.vf trans trans) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 pair-quaternion-ready-1 :delay (sub.vf quat zero-vf quat)) + (label pair-quaternion-ready-1) + (itof.vf trans-b trans-b) + (add.vf out-quat out-quat quat) + (mula.w.vf out-trans vf0) + (madda.y.vf trans weight-vf) + (madd.z.vf out-trans trans-b weight-vf) + (s.vf out-quat frame 16) + (s.vf out-trans frame) + (b pair-next-transform :delay (nop!)) + ;; control nibble 11: the set bits, decoded from both frames and blended + (label pair-path-quat-wide-trans) + (l.d xfer stream64 8) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d xfer stream64-b 8) + (add.i stream64-b stream64-b 8) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat-b xfer) + (itof.vf quat quat :fixed 15) + (l.d pack stream64 -8) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (itof.vf quat-b quat-b :fixed 15) + (l.vf out-trans frame) + (pcpyld pack pack-hi pack) + (mula.x.vf quat weight-vf) + (madd.w.vf quat quat-b weight-vf) + (m trans pack) + (mul.vf dot quat out-quat) + (l.d pack stream64-b -8) + (add.i stream64-b stream64-b 8) + (l.w pack-hi stream32-b) + (add.i stream32-b stream32-b 4) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (pcpyld pack pack-hi pack) + (m xfer dot) + (m trans-b pack) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 pair-quaternion-ready-2 :delay (sub.vf quat zero-vf quat)) + (label pair-quaternion-ready-2) + (add.vf out-quat out-quat quat) + (mula.w.vf out-trans vf0) + (madda.x.vf trans weight-vf) + (madd.w.vf out-trans trans-b weight-vf) + (s.vf out-quat frame 16) + (s.vf out-trans frame) + (b pair-next-transform :delay (nop!)) + ;; control nibble 4, 12: the set bits, decoded from both frames and blended + (label pair-path-scale) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (l.w pack2 stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack2-hi stream16-b) + (add.i stream16-b stream16-b 2) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale-b pack2) + (itof.vf scale scale :fixed 12) + (itof.vf scale-b scale-b :fixed 12) + (mula.w.vf out-scale vf0) + (madda.x.vf scale weight-vf) + (madd.w.vf out-scale scale-b weight-vf) + (s.vf out-scale frame 32) + (b pair-next-transform :delay (nop!)) + ;; control nibble 5: the set bits, decoded from both frames and blended + (label pair-path-trans-scale) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-trans frame) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans pack) + (l.w pack stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack-hi stream16-b) + (add.i stream16-b stream16-b 2) + (pextlw pack pack-hi pack) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans-b pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (itof.vf trans trans) + (itof.vf trans-b trans-b) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (mula.w.vf out-trans vf0) + (madda.y.vf trans weight-vf) + (madd.z.vf out-trans trans-b weight-vf) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (l.w pack2 stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack2-hi stream16-b) + (add.i stream16-b stream16-b 2) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale-b pack2) + (itof.vf scale scale :fixed 12) + (itof.vf scale-b scale-b :fixed 12) + (mula.w.vf out-scale vf0) + (madda.x.vf scale weight-vf) + (madd.w.vf out-scale scale-b weight-vf) + (s.vf out-trans frame) + (s.vf out-scale frame 32) + (b pair-next-transform :delay (nop!)) + ;; control nibble 13: the set bits, decoded from both frames and blended + (label pair-path-wide-trans-scale) + (l.d pack stream64) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (l.vf out-trans frame) + (pcpyld pack pack-hi pack) + (m trans pack) + (l.d pack stream64-b) + (add.i stream64-b stream64-b 8) + (l.w pack-hi stream32-b) + (add.i stream32-b stream32-b 4) + (pcpyld pack pack-hi pack) + (m trans-b pack) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (mula.w.vf out-trans vf0) + (madda.x.vf trans weight-vf) + (madd.w.vf out-trans trans-b weight-vf) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (l.w pack2 stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack2-hi stream16-b) + (add.i stream16-b stream16-b 2) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale-b pack2) + (itof.vf scale scale :fixed 12) + (itof.vf scale-b scale-b :fixed 12) + (mula.w.vf out-scale vf0) + (madda.x.vf scale weight-vf) + (madd.w.vf out-scale scale-b weight-vf) + (s.vf out-trans frame) + (s.vf out-scale frame 32) + (b pair-next-transform :delay (nop!)) + ;; control nibble 6, 14: the set bits, decoded from both frames and blended + (label pair-path-quat-scale) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d xfer stream64-b) + (add.i stream64-b stream64-b 8) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat-b xfer) + (itof.vf quat quat :fixed 15) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (itof.vf quat-b quat-b :fixed 15) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (mula.x.vf quat weight-vf) + (madd.w.vf quat quat-b weight-vf) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (mul.vf dot quat out-quat) + (l.w pack2 stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack2-hi stream16-b) + (add.i stream16-b stream16-b 2) + (pextlw pack2 pack2-hi pack2) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale-b pack2) + (m xfer dot) + (itof.vf scale scale :fixed 12) + (itof.vf scale-b scale-b :fixed 12) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 pair-quaternion-ready-3 :delay (sub.vf quat zero-vf quat)) + (label pair-quaternion-ready-3) + (mula.w.vf out-scale vf0) + (madda.x.vf scale weight-vf) + (madd.w.vf out-scale scale-b weight-vf) + (add.vf out-quat out-quat quat) + (s.vf out-quat frame 16) + (s.vf out-scale frame 32) + (b pair-next-transform :delay (nop!)) + ;; control nibble 7: the set bits, decoded from both frames and blended + (label pair-path-quat-trans-scale) + (l.d xfer stream64) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d xfer stream64-b) + (add.i stream64-b stream64-b 8) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat-b xfer) + (l.w pack stream32) + (add.i stream32 stream32 4) + (l.h pack-hi stream16) + (add.i stream16 stream16 2) + (itof.vf quat quat :fixed 15) + (itof.vf quat-b quat-b :fixed 15) + (l.vf out-trans frame) + (pextlw pack pack-hi pack) + (mula.x.vf quat weight-vf) + (madd.w.vf quat quat-b weight-vf) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans pack) + (mul.vf dot quat out-quat) + (l.w pack stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack-hi stream16-b) + (add.i stream16-b stream16-b 2) + (pextlw pack pack-hi pack) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (pextlh pack pack r0) + (sra.w pack pack 16) + (m trans-b pack) + (m xfer dot) + (itof.vf trans trans) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 pair-quaternion-ready-4 :delay (sub.vf quat zero-vf quat)) + (label pair-quaternion-ready-4) + (itof.vf trans-b trans-b) + (mula.w.vf out-trans vf0) + (madda.y.vf trans weight-vf) + (madd.z.vf out-trans trans-b weight-vf) + (add.vf out-quat out-quat quat) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (l.w pack2 stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack2-hi stream16-b) + (add.i stream16-b stream16-b 2) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale-b pack2) + (itof.vf scale scale :fixed 12) + (itof.vf scale-b scale-b :fixed 12) + (mula.w.vf out-scale vf0) + (madda.x.vf scale weight-vf) + (madd.w.vf out-scale scale-b weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (s.vf out-scale frame 32) + (b pair-next-transform :delay (nop!)) + ;; control nibble 15: the set bits, decoded from both frames and blended + (label pair-path-quat-wide-trans-scale) + (l.d xfer stream64 8) + (add.i stream64 stream64 8) + (l.vf out-quat frame 16) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat xfer) + (l.d xfer stream64-b 8) + (add.i stream64-b stream64-b 8) + (pextlh xfer xfer r0) + (sra.w xfer xfer 16) + (m quat-b xfer) + (l.d pack stream64 -8) + (add.i stream64 stream64 8) + (l.w pack-hi stream32) + (add.i stream32 stream32 4) + (itof.vf quat quat :fixed 15) + (itof.vf quat-b quat-b :fixed 15) + (l.vf out-trans frame) + (pcpyld pack pack-hi pack) + (mula.x.vf quat weight-vf) + (madd.w.vf quat quat-b weight-vf) + (m trans pack) + (mul.vf dot quat out-quat) + (l.d pack stream64-b -8) + (add.i stream64-b stream64-b 8) + (l.w pack-hi stream32-b) + (add.i stream32-b stream32-b 4) + (pcpyld pack pack-hi pack) + (mula.w.vf dot vf0) + (madda.z.vf vf0 dot) + (madda.y.vf vf0 dot) + (madd.x.vf dot vf0 dot) + (m trans-b pack) + (m xfer dot) + (l.w pack2 stream32) + (add.i stream32 stream32 4) + (l.h pack2-hi stream16) + (add.i stream16 stream16 2) + (pcpyud xfer xfer r0) + (b.ltl xfer r0 pair-quaternion-ready-5 :delay (sub.vf quat zero-vf quat)) + (label pair-quaternion-ready-5) + (mula.w.vf out-trans vf0) + (madda.x.vf trans weight-vf) + (madd.w.vf out-trans trans-b weight-vf) + (add.vf out-quat out-quat quat) + (l.vf out-scale frame 32) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale pack2) + (l.w pack2 stream32-b) + (add.i stream32-b stream32-b 4) + (l.h pack2-hi stream16-b) + (add.i stream16-b stream16-b 2) + (pextlw pack2 pack2-hi pack2) + (pextlh pack2 pack2 r0) + (sra.w pack2 pack2 16) + (m scale-b pack2) + (itof.vf scale scale :fixed 12) + (itof.vf scale-b scale-b :fixed 12) + (mula.w.vf out-scale vf0) + (madda.x.vf scale weight-vf) + (madd.w.vf out-scale scale-b weight-vf) + (s.vf out-trans frame) + (s.vf out-quat frame 16) + (s.vf out-scale frame 32) + (b pair-next-transform :delay (nop!)) + (label pair-return) + (l.q frame sp) + (l.q stream64-b sp 16) + (l.q stream32-b sp 32) + (l.q stream16-b sp 48) + (jr ra :delay (add.i sp sp 64)) + (jr ra :delay (add sp sp r0)) + (nop!) + (nop!)))) + + + +(#when PC_PORT + (define-extern decompress-fixed-data-to-accumulator (function none)) + (define-extern decompress-frame-data-to-accumulator (function none)) + (define-extern decompress-frame-data-pair-to-accumulator (function none))) + +(defun make-joint-jump-tables () + "Install the 16 control-nibble destinations for each of the three decompressors, in spad. + Indexing on the whole nibble lets a transform with no scale skip the scale code entirely + instead of testing for it." + ;; The numbers are instruction offsets into each assembly function, so they only mean anything + ;; against that function's own instruction stream; the (label *-path-*) names in the + ;; decompressors sit at exactly these offsets. fix-jmp-table takes the clear bits, meaning the + ;; components present in the fixed streams: + ;; 0 -> trans-quat-scale 8 -> wide-trans-quat-scale + ;; 1 -> quat-scale 9 -> quat-scale (bit 3 is meaningless with no trans) + ;; 2 -> trans-scale 10 -> wide-trans-scale + ;; 3 -> scale 11 -> scale + ;; 4 -> trans-quat 12 -> wide-trans-quat + ;; 5 -> quat 13 -> quat + ;; 6 -> trans 14 -> wide-trans + ;; 7 -> nothing 15 -> nothing (straight to fixed-next-transform) + ;; frm-jmp-table and pair-jmp-table take the set bits, so their tables are the same list read + ;; the other way round: 0 and 8 are the nothing case and 15 is all three with wide translation. + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 0) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 108 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 1) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 2) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 233 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 3) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 4) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 301 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 5) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 6) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 387 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 7) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 8) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 155 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 9) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 10) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 261 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 11) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 12) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 335 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 13) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 14) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 402 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 15) + (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 0) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 1) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 92 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 2) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 3) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 140 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 4) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 5) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 220 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 6) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 7) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 307 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 8) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 9) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 107 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 10) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 11) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 174 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 12) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 13) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 248 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 14) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 15) + (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 354 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 0) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 1) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 125 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 2) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 3) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 197 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 4) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 5) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 318 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 6) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 7) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 459 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 8) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 9) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 150 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 10) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 11) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 248 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 12) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 13) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 366 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 14) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4)))) + (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 15) + (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 533 4)))) + 0) + +(#when PC_PORT + (def-mips2c calc-animation-from-spr (function (inline-array vector) int none))) + +(#unless PC_PORT + (defun calc-animation-from-spr ((destination (inline-array vector)) (joint-count int)) + "Run the upload list that flatten-joint-control-to-spr left in spad: clear the frame, then DMA + and accumulate each animation's fixed and frame data, then renormalize. Every DMA is started one + step ahead of the code that consumes it." + (declare (asm-func object) (allow-saved-regs)) + (rlet ((to-spr-channel :reg s0 :type dma-bank-spr) + (uploads-left :reg s1) + (saved-joint-count :reg s2) + (upload :reg t7) + (control-copy :reg t1) + (dma-address :reg t2) + (scratchpad-address :reg t3) + (quadword-count :reg t4) + (dma-control :reg v1) + (interpolation :reg t0) + (weight :reg a2) + (frame-data :reg a1) + (second-frame-offset :reg a3) + (zero :reg vf15) + (one :reg vf14)) + (m! saved-joint-count joint-count) + (m! uploads-left (-> (scratchpad-object terrain-context) work foreground joint-work num-uploads)) + (m! upload (-> (scratchpad-object terrain-context) work foreground joint-work uploads)) + (m! control-copy (&+ (scratchpad-object terrain-context) (joint-spad-offset jacp-hdr))) + ;; SPR_TO_BANK. This moves main memory into spad, so it is the toSPR channel. + (m! to-spr-channel #x1000d400) + ;; one is the broadcast scale vector that the decompressors multiply the blend weight by. + ;; All four lanes start at 1, then two doublings of y and z leave (1, 4, 4, 1). The 4 is the + ;; compact translation's fixed-point factor, carried here rather than in the tables. + (m zero r0) + (b.z uploads-left animation-complete :delay (add.w.vf one zero vf0)) + (label next-upload) + ;; Start the fixed block's DMA into spad and run clear-frame-accumulator underneath it. Both + ;; sync.l are needed, since the qwc and madr stores must be visible before str goes on. + (l.w dma-address upload) + (m! scratchpad-address (joint-spad-offset fixed-data)) + (l.w quadword-count upload (offset-of channel-upload-info fixed-qwc)) + (m! dma-control DMA-CHCR-STR) + (s.w dma-address (-> to-spr-channel madr)) + (s.w scratchpad-address (-> to-spr-channel sadr)) + (nop!) + (s.w quadword-count (-> to-spr-channel qwc)) + (sync.l) + (s.w dma-control (-> to-spr-channel chcr)) + (sync.l) + (add.yz.vf one one one) + (m! saved-joint-count joint-count) + (jalr ra clear-frame-accumulator :delay (add.yz.vf one one one)) + (label wait-fixed) + (l.w dma-control (-> to-spr-channel chcr)) + (nop!) + (and.i dma-control dma-control DMA-CHCR-STR) + (nop!) + (nop!) + (nop!) + (b.nz dma-control wait-fixed :delay (nop!)) + ;; Queue the first frame, then work through the fixed block while that DMA runs. + (l.w dma-address upload (offset-of channel-upload-info frame)) + (m! scratchpad-address (joint-spad-offset frame-data)) + (l.w quadword-count upload (offset-of channel-upload-info frame-qwc)) + (m! dma-control DMA-CHCR-STR) + (s.w dma-address (-> to-spr-channel madr)) + (nop!) + (s.w scratchpad-address (-> to-spr-channel sadr)) + (nop!) + (s.w quadword-count (-> to-spr-channel qwc)) + (sync.l) + (s.w dma-control (-> to-spr-channel chcr)) + (sync.l) + (l.w weight upload (offset-of channel-upload-info amount)) + (m! frame-data (&+ (scratchpad-object terrain-context) (joint-spad-offset fixed-data))) + (-! uploads-left 1) + (jalr ra decompress-fixed-data-to-accumulator :delay (nop!)) + (label wait-frame) + (l.w dma-control (-> to-spr-channel chcr)) + (nop!) + (and.i dma-control dma-control DMA-CHCR-STR) + (nop!) + (nop!) + (nop!) + (b.nz dma-control wait-frame :delay (nop!)) + ;; If requests remain, start the next one's fixed DMA before decoding this frame. Reading + ;; one channel-upload-info past this record is deliberate. + (b.z uploads-left frame-ready :delay (nop!)) + (l.w dma-address upload (+ (type-size channel-upload-info) (offset-of channel-upload-info fixed))) + (m! scratchpad-address (joint-spad-offset fixed-data)) + (l.w quadword-count upload (+ (type-size channel-upload-info) (offset-of channel-upload-info fixed-qwc))) + (m! dma-control DMA-CHCR-STR) + (s.w dma-address (-> to-spr-channel madr)) + (nop!) + (s.w scratchpad-address (-> to-spr-channel sadr)) + (nop!) + (s.w quadword-count (-> to-spr-channel qwc)) + (sync.l) + (s.w dma-control (-> to-spr-channel chcr)) + (sync.l) + (label frame-ready) + (l.w interpolation upload (offset-of channel-upload-info interp)) + (m! frame-data (&+ (scratchpad-object terrain-context) (joint-spad-offset frame-data))) + (l.w weight upload (offset-of channel-upload-info amount)) + ;; A nonzero interp means flatten-joint-control-to-spr doubled frame-qwc and brought the next + ;; frame across right behind this one, so the pair decoder gets the stride in bytes. + (b.z interpolation single-frame :delay (nop!)) + (l.w second-frame-offset upload (offset-of channel-upload-info frame-qwc)) + (sll second-frame-offset second-frame-offset 3) + (jalr ra decompress-frame-data-pair-to-accumulator :delay (nop!)) + (b.nz uploads-left next-upload :delay (&+! upload (type-size channel-upload-info))) + (b normalize-result :delay (nop!)) + (label single-frame) + (jalr ra decompress-frame-data-to-accumulator :delay (nop!)) + (b.nz uploads-left next-upload :delay (&+! upload (type-size channel-upload-info))) + (label normalize-result) + (m! saved-joint-count joint-count) + (jalr ra normalize-frame-quaternions :delay (nop!)) + (label animation-complete) + (jr ra :delay (nop!))))) + + +(#unless PC_PORT + (defun cspace<-parented-transformq-joint! ((space cspace) (xform transformq)) + "Build a local matrix from xform, compensate for parent scale when present, and concatenate it + with the parent bone transform." + (rlet ((parent (-> space parent)) + (parent-matrix (-> parent bone transform)) + (bone (-> space bone)) + (bone-matrix (-> bone transform)) + (quat :reg vf5) + (double-quat :reg vf6) + (translation :reg vf15) + (joint-scale :reg vf1) + (row-x :reg vf2) + (row-y :reg vf3) + (row-z :reg vf4) + (parent-x :reg vf7) + (parent-y :reg vf8) + (parent-z :reg vf9) + (parent-t :reg vf10) + (world-x :reg vf11) + (world-y :reg vf12) + (world-z :reg vf13) + (world-t :reg vf14) + (reciprocal-parent-scale :reg vf16) + (packed-reciprocals :class i128) + (one-bits) + (reciprocal-x) + (reciprocal-y) + (reciprocal-z) + (parent-has-scale?)) + (nop!) + (m! one-bits 1.0) + (l.vf quat xform 16) + (l.vf translation xform) + (l.vf joint-scale xform 32) + (l.vf parent-x parent-matrix) + (l.vf parent-y parent-matrix 16) + (l.vf parent-z parent-matrix 32) + (l.vf parent-t parent-matrix 48) + (add.vf double-quat quat quat) + ;; Expand the quaternion into three rotation rows. The outer products supply the cross terms; + ;; adding one to the diagonal completes the standard unit-quaternion matrix. + (add.w.vf.x row-x vf0 quat) + (add.z.vf.y row-x vf0 quat) + (sub.y.vf.z row-x vf0 quat) + (sub.w.vf.w row-x vf0 vf0) + (sub.z.vf.x row-y vf0 quat) + (add.w.vf.y row-y vf0 quat) + (add.x.vf.z row-y vf0 quat) + (sub.w.vf.w row-y vf0 vf0) + (add.y.vf.x row-z vf0 quat) + (sub.x.vf.y row-z vf0 quat) + (add.w.vf.z row-z vf0 quat) + (sub.w.vf.w row-z vf0 vf0) + (outer.product.a.vf acc double-quat row-x) + (outer.product.b.vf row-x row-x double-quat acc) + (outer.product.a.vf acc double-quat row-y) + (outer.product.b.vf row-y row-y double-quat acc) + (outer.product.a.vf acc double-quat row-z) + (outer.product.b.vf row-z row-z double-quat acc) + (add.w.vf.x row-x row-x vf0) + (add.w.vf.y row-y row-y vf0) + (add.w.vf.z row-z row-z vf0) + (mul.x.vf row-x row-x joint-scale) + (mul.y.vf row-y row-y joint-scale) + (mul.z.vf row-z row-z joint-scale) + (l.w parent-has-scale? parent-matrix 76) + (b.z parent-has-scale? compose :delay (div.s reciprocal-z 1.0 (-> parent-matrix data 18))) + ;; A scaled parent records that fact in scale.w. Divide its basis scale out before multiplying + ;; so the child's authored scale is not compounded a second time. + (div.s reciprocal-x 1.0 (-> parent-matrix data 16)) + (div.s reciprocal-y 1.0 (-> parent-matrix data 17)) + (m packed-reciprocals reciprocal-x) + (pextlw packed-reciprocals reciprocal-y packed-reciprocals) + (pcpyld packed-reciprocals reciprocal-z packed-reciprocals) + (m reciprocal-parent-scale packed-reciprocals) + (mul.vf row-x row-x reciprocal-parent-scale) + (mul.vf row-y row-y reciprocal-parent-scale) + (mul.vf row-z row-z reciprocal-parent-scale) + (label compose) + (mula.x.vf parent-x row-x) + (madda.y.vf parent-y row-x) + (madda.z.vf parent-z row-x) + (madd.w.vf world-x parent-t row-x) + (mula.x.vf parent-x row-y) + (madda.y.vf parent-y row-y) + (madda.z.vf parent-z row-y) + (madd.w.vf world-y parent-t row-y) + (mula.x.vf parent-x row-z) + (madda.y.vf parent-y row-z) + (madda.z.vf parent-z row-z) + (madd.w.vf world-z parent-t row-z) + (mula.x.vf parent-x translation) + (madda.y.vf parent-y translation) + (madda.z.vf parent-z translation) + (madd.w.vf world-t parent-t vf0) + (s.vf joint-scale bone 64) + (s.vf world-x bone-matrix) + (s.vf world-y bone-matrix 16) + (s.vf world-z bone-matrix 32) + (jr ra :delay (s.vf world-t bone-matrix 48))))) \ No newline at end of file diff --git a/goal_src/jak1/engine/anim/joint-h.gc b/goal_src/jak1/engine/anim/joint-h.gc index fb6024de43..f19a73ade3 100644 --- a/goal_src/jak1/engine/anim/joint-h.gc +++ b/goal_src/jak1/engine/anim/joint-h.gc @@ -20,7 +20,7 @@ (define-extern create-interpolated-joint-animation-frame "Generate a drawable's blended joint animation frame." - (function (inline-array vector) int process-drawable int)) + (function joint-anim-frame int process-drawable none)) (defenum janim-status :type uint16 @@ -65,7 +65,7 @@ (root-channel (inline-array joint-control-channel) :offset 16) (blend-index int32) (active-channels int32) - (generate-frame-function (function (inline-array vector) int process-drawable int)) + (generate-frame-function (function joint-anim-frame int process-drawable none)) (prebind-function (function pointer int process-drawable none)) (postbind-function (function process-drawable none)) (effect effect-control) diff --git a/goal_src/jak1/engine/anim/joint.gc b/goal_src/jak1/engine/anim/joint.gc index 21aeaa3da1..e3b45c2c9e 100644 --- a/goal_src/jak1/engine/anim/joint.gc +++ b/goal_src/jak1/engine/anim/joint.gc @@ -53,9 +53,7 @@ ;; sees short, several second long animations. ;; Animations for jak (walking, jumping, etc) are not streamed since there would be too much latency to wait for the DVD drive. -;; Some of these animations are wrapped in LZO compression. This requires decompressing the entire animation to access it. -;; To avoid redoing the LZO compression on every frame, there is a LZO animation decompression cache. Ideally, the animation -;; is decompressed once on the first frame its used, then remains in the cache while it's in use. +;; Some of these animations are wrapped in LZO compression in Jak 2 and 3. ;; Additionally, all animations have their own inner compression format. This format is designed for speed and ease of decompression, ;; and is designed so you can seek to an arbitrary frame. The decompressor is stateless - if frame n + 1 is decompressed after frame n, @@ -168,6 +166,9 @@ ;; ---- Inner decompression format ---- ;; The compressed format is relatively simple. +;; It stores the transformation between bones (joint transforms) as either a matrix or a transformq. +;; The joint transformations use the standard convention of autodesk Maya where the scale component +;; of the transform is only applied to an immediate child and not propagated. ;; There is a "fixed" data for an entire animation, and "frame data": one for each frame. ;; Each data has some u64's, u32's, and u16's. @@ -704,7 +705,9 @@ "Print the command, animation, artist-frame position, interpolation, and final weight of every active channel." (dotimes (i (-> this active-channels)) - (let* ((v1-6 (if (and (-> this channel i frame-group) (nonzero? (-> this channel i frame-group))) (-> this channel i frame-group)))) + (let* ((group (if (and (-> this channel i frame-group) + (nonzero? (-> this channel i frame-group))) + (-> this channel i frame-group)))) (format output "ch:~2d ~C ~-35S f: ~6,,2f ~4,,2f ~4,,2f%~%" i ;; channel index @@ -714,9 +717,9 @@ (('blend) 66) (('stack) 83) (('stack1) 115)) - (if v1-6 (-> v1-6 name) "(none)") ;; name of anim (can be "none" in the real game) - (+ (* (-> this channel i frame-num) (if v1-6 (-> v1-6 artist-step) 1.0)) ;; frame number - (if v1-6 (-> v1-6 artist-base) 0.0)) + (if group (-> group name) "(none)") ;; name of anim (can be "none" in the real game) + (+ (* (-> this channel i frame-num) (if group (-> group artist-step) 1.0)) ;; frame number + (if group (-> group artist-base) 0.0)) (-> this channel i frame-interp) (-> this channel i inspector-amount)))) 0) @@ -760,33 +763,20 @@ ;; not sure why we have to do this, but if the res-lump isn't properly set up to point to the tags ;; do it manually. It seems like the linker could have done this?? (if (and (-> this extra) (zero? (-> this extra tag))) - (set! (-> this extra tag) (&+ (the-as (pointer res-tag) (-> this extra)) 28))) + (set! (-> this extra tag) (&+ (the-as (pointer res-tag) (-> this extra)) 28))) this) (defmethod mem-usage ((this art-mesh-anim) (usage memory-usage-block) (flags mem-usage-flags)) "Account for this mesh animation, its resource lump, and every payload object." (mem-usage-add! usage art-mesh-anim 1 (asize-of this)) ;; setting the flag makes the res-lump's memory count toward joint-geo. - (if (-> this extra) (mem-usage (-> this extra) usage (logior flags (mem-usage-flags resource-joint-geo)))) - (dotimes (s3-0 (-> this length)) - (mem-usage (-> this data s3-0) usage flags)) + (if (-> this extra) + (mem-usage (-> this extra) usage (logior flags (mem-usage-flags resource-joint-geo)))) + (dotimes (i (-> this length)) + (mem-usage (-> this data i) usage flags)) this) -(defmethod mem-usage ((this art-joint-anim) (usage memory-usage-block) (flags mem-usage-flags)) - "Account for this animation group, compressed frame storage, eye animation data, and resource - lump." - (mem-usage-add! usage art-joint-anim 1 (asize-of this)) - (if (-> this extra) (mem-usage (-> this extra) usage (logior flags (mem-usage-flags resource-joint-geo)))) - (jacc-mem-usage (-> this frames) usage flags) - (dotimes (s4-1 (-> this length)) - (mem-usage-add! usage joint-anim-compressed 1 (asize-of (-> this data s4-1)))) - (when (and (nonzero? (-> this eye-anim-data)) (-> this eye-anim-data)) - (mem-usage-add! usage eye-anim 1 (* (* (+ (-> this eye-anim-data max-frame) 1) 2) 8))) - this) - -(defmethod asize-of ((this art-joint-anim)) - "Return the art header size plus one pointer-sized entry per compressed animation." - (the-as int (+ (-> art size) (* (-> this length) 4)))) +;; asize-of art-joint-anim was defined twice, first here (defmethod inspect ((this art-joint-anim)) (format #t "[~8x] ~A~%" this (-> this type)) @@ -804,6 +794,22 @@ (format #t "~T [~D] ~A~%" i (-> this data i))) this) +(defmethod mem-usage ((this art-joint-anim) (usage memory-usage-block) (flags mem-usage-flags)) + "Account for this animation group, compressed frame storage, eye animation data, and resource + lump." + (mem-usage-add! usage art-joint-anim 1 (asize-of this)) + (if (-> this extra) (mem-usage (-> this extra) usage (logior flags (mem-usage-flags resource-joint-geo)))) + (jacc-mem-usage (-> this frames) usage flags) + (dotimes (s4-1 (-> this length)) + (mem-usage-add! usage joint-anim-compressed 1 (asize-of (-> this data s4-1)))) + (when (and (nonzero? (-> this eye-anim-data)) (-> this eye-anim-data)) + (mem-usage-add! usage eye-anim 1 (* (* (+ (-> this eye-anim-data max-frame) 1) 2) 8))) + this) + +;; asize-of art-joint-anim was defined again here +(defmethod asize-of ((this art-joint-anim)) + (the-as int (+ (-> art size) (* (-> this length) 4)))) + (defmethod inspect ((this art-group)) "Print the arts in an art-group" (format #t "[~8x] ~A~%" this (-> this type)) @@ -843,7 +849,8 @@ (else ;; no type (also no weird after ag name check) (dotimes (s4-1 (-> this length)) - (if (and (-> this data s4-1) (name= art-name (-> this data s4-1 name))) (return (the-as joint (-> this data s4-1))))) + (if (and (-> this data s4-1) (name= art-name (-> this data s4-1 name))) + (return (the-as joint (-> this data s4-1))))) (the-as art-element #f))))) (defmethod lookup-idx-of-art ((this art-group) (art-name string) (expected-type type)) @@ -860,19 +867,22 @@ (the-as int #f)) (else (dotimes (s4-1 (-> this length)) - (if (and (-> this data s4-1) (name= art-name (-> this data s4-1 name))) (return s4-1))) + (if (and (-> this data s4-1) (name= art-name (-> this data s4-1 name))) + (return s4-1))) (the-as int #f)))) (defmethod login ((this art-group)) "Log in all the arts in a group." (dotimes (s5-0 (-> this length)) - (if (-> this data s5-0) (set! (-> this data s5-0) (login (-> this data s5-0))))) + (if (-> this data s5-0) + (set! (-> this data s5-0) (login (-> this data s5-0))))) this) (defmethod mem-usage ((this art-group) (usage memory-usage-block) (flags mem-usage-flags)) "Account for this art group, its resource lump, and every populated art entry." (mem-usage-add! usage art-group 1 (asize-of this)) - (if (-> this extra) (mem-usage (-> this extra) usage (logior flags (mem-usage-flags resource-joint-geo)))) + (if (-> this extra) + (mem-usage (-> this extra) usage (logior flags (mem-usage-flags resource-joint-geo)))) (dotimes (s3-0 (-> this length)) (if (-> this data s3-0) (mem-usage (-> this data s3-0) usage flags))) this) @@ -883,15 +893,20 @@ (string<-charp s4-0 name) (set! this (cond - ((not this) (format 0 "ERROR: art-group ~A is not a valid file.~%" s4-0) (the-as art-group #f)) + ((not this) + (format 0 "ERROR: art-group ~A is not a valid file.~%" s4-0) + (the art-group #f)) ((not (type-type? (-> this type) art-group)) (format 0 "ERROR: art-group ~A is not a art-group.~%" s4-0) - (the-as art-group #f)) - ((not (file-info-correct-version? (-> this info) (file-kind art-group) 0)) (the-as art-group #f)) + (the art-group #f)) + ((not (file-info-correct-version? (-> this info) (file-kind art-group) 0)) + (the art-group #f)) (else (let ((s5-1 (-> *level* loading-level))) - (if (or (not s5-1) (= (-> s5-1 name) 'default)) (login this)) ;; not part of level load, just normal login. - (if s5-1 (set-loaded-art (-> s5-1 art-group) this))) ;; part of level load, add to level's ag, but don't log in yet. + (if (or (not s5-1) (= (-> s5-1 name) 'default)) + (login this)) ;; not part of level load, just normal login. + (if s5-1 + (set-loaded-art (-> s5-1 art-group) this))) ;; part of level load, add to level's ag, but don't log in yet. this)))) (none)) @@ -920,7 +935,7 @@ (defmethod login ((this art-joint-anim)) "Prepare this animation group's optional resource lump for use." (if (and (-> this extra) (zero? (-> this extra tag))) - (set! (-> this extra tag) (&+ (the-as (pointer res-tag) (-> this extra)) 28))) + (set! (-> this extra tag) (&+ (the-as (pointer res-tag) (-> this extra)) 28))) this) (defmethod asize-of ((this art-joint-geo)) @@ -933,11 +948,12 @@ (expected-type (dotimes (s3-0 (-> this length)) (if (and (= (-> this data s3-0 type) expected-type) (name= joint-name (-> this data s3-0 name))) - (return (-> this data s3-0)))) + (return (-> this data s3-0)))) (the-as joint #f)) (else (dotimes (s4-1 (-> this length)) - (if (name= joint-name (-> this data s4-1 name)) (return (-> this data s4-1)))) + (if (name= joint-name (-> this data s4-1 name)) + (return (-> this data s4-1)))) (the-as joint #f)))) (defmethod lookup-idx-of-art ((this art-joint-geo) (joint-name string) (expected-type type)) @@ -945,20 +961,27 @@ (cond (expected-type (dotimes (s3-0 (-> this length)) - (if (and (= (-> this data s3-0 type) expected-type) (name= joint-name (-> this data s3-0 name))) (return s3-0))) + (if (and (= (-> this data s3-0 type) expected-type) + (name= joint-name (-> this data s3-0 name))) + (return s3-0))) (the-as int #f)) - (else (dotimes (s4-1 (-> this length)) (if (name= joint-name (-> this data s4-1 name)) (return s4-1))) (the-as int #f)))) + (else + (dotimes (s4-1 (-> this length)) + (if (name= joint-name (-> this data s4-1 name)) + (return s4-1))) + (the-as int #f)))) (defmethod mem-usage ((this art-joint-geo) (usage memory-usage-block) (flags mem-usage-flags)) "Account for this joint geometry, its resource lump, and every joint descriptor." (mem-usage-add! usage art-joint-geo 1 (asize-of this)) - (if (-> this extra) (mem-usage (-> this extra) usage (logior flags (mem-usage-flags resource-joint-geo)))) + (if (-> this extra) + (mem-usage (-> this extra) usage (logior flags (mem-usage-flags resource-joint-geo)))) (dotimes (s3-0 (-> this length)) (mem-usage (-> this data s3-0) usage flags)) this) ;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Joint Control! +;; Joint Control ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; the confusing thing here is a "group" just refers to a "frame-group", which is @@ -1018,7 +1041,8 @@ (the-as (inline-array joint-control-channel) (-> destination channel - (/ (&- (the-as pointer (-> source root-channel)) (the-as uint (the-as pointer (-> source channel)))) 48)))) + (/ (&- (the-as pointer (-> source root-channel)) + (the-as uint (the-as pointer (-> source channel)))) 48)))) (mem-copy! (the-as pointer (-> destination channel)) (the-as pointer (-> source channel)) (* 48 (-> destination allocated-length))) @@ -1061,146 +1085,6 @@ (set! all-matched? (the-as symbol #f))))))))) all-matched?)) -(defun flatten-joint-control-to-spr ((control joint-control)) - "Evaluate the controller's blend tree into 24 per-channel weights in spad, then fill in the - channel-upload-info list that the spad decompressor works from. A nonzero interp doubles - frame-qwc so the next frame comes across in the same DMA. The final weights are also copied to - inspector-amount for the debug display. - vf2 through vf14 keep physical names, because the blend and stack arms use them for unrelated - values." - (rlet ((weight-bcast :class vf) - (vf10 :class vf) - (vf11 :class vf) - (vf12 :class vf) - (vf13 :class vf) - (vf14 :class vf) - (vf2 :class vf) - (vf3 :class vf) - (vf4 :class vf) - (vf5 :class vf) - (vf6 :class vf) - (vf7 :class vf) - (vf8 :class vf) - (vf9 :class vf)) - (let ((channel-count (-> control active-channels))) - (let ((one 1.0) - (weight-offset 0) ;; this channel's float within a stack frame, bumped by 4 per channel - (frame-top (-> (scratchpad-object terrain-context) work foreground joint-work flattened))) - ;; A postfix blend tree. push starts an animation on a new stack frame, blend and push1 - ;; crossfade the top frame toward their channel, and stack combines and pops the top two. - ;; A stack frame is 24 weights, so six quads, and all six are scaled every time. - (dotimes (chan-idx channel-count) - (let ((chan (-> control channel chan-idx))) - (case (-> chan command) - (('push) - ;; Start with every channel at zero and this channel at one. - (let ((weight-slot (&+ (the-as pointer frame-top) weight-offset))) - (set! (-> frame-top 0 quad) (the-as uint128 0)) - (set! (-> frame-top 1 quad) (the-as uint128 0)) - (set! (-> frame-top 2 quad) (the-as uint128 0)) - (set! (-> frame-top 3 quad) (the-as uint128 0)) - (set! (-> frame-top 4 quad) (the-as uint128 0)) - (set! (-> frame-top 5 quad) (the-as uint128 0)) - ;; and this thing stores the normal weight. - (set! (-> (the-as (pointer float) weight-slot)) one)) - ;; advance. - (set! frame-top (the-as (inline-array vector) (-> frame-top 6)))) - (('blend 'push1) - (let ((new-weight (-> chan frame-interp))) - (let ((old-weight (- one new-weight))) (.mov weight-bcast old-weight)) - (let ((sf (the-as (inline-array vector) (-> frame-top -6)))) - (.lvf vf2 (&-> sf 0 quad)) - (let ((sf-weight-slot (&+ (the-as pointer sf) weight-offset))) - (.lvf vf3 (&-> sf 1 quad)) - (.lvf vf4 (&-> sf 2 quad)) - (.lvf vf5 (&-> sf 3 quad)) - (.lvf vf6 (&-> sf 4 quad)) - (.lvf vf7 (&-> sf 5 quad)) - (.mul.x.vf vf2 vf2 weight-bcast) - (.mul.x.vf vf3 vf3 weight-bcast) - (.mul.x.vf vf4 vf4 weight-bcast) - (.mul.x.vf vf5 vf5 weight-bcast) - (.mul.x.vf vf6 vf6 weight-bcast) - (.mul.x.vf vf7 vf7 weight-bcast) - (.svf (&-> sf 0 quad) vf2) - (.svf (&-> sf 1 quad) vf3) - (.svf (&-> sf 2 quad) vf4) - (.svf (&-> sf 3 quad) vf5) - (.svf (&-> sf 4 quad) vf6) - (.svf (&-> sf 5 quad) vf7) - (set! (-> (the-as (pointer float) sf-weight-slot)) (+ (-> (the-as (pointer float) sf-weight-slot) 0) new-weight))) - (set! frame-top (the-as (inline-array vector) (-> sf 6)))))) - (('stack) - (let* ((top-weight (-> chan frame-interp)) - (lower-weight (- one top-weight)) - (sf0 (the-as (inline-array vector) (-> frame-top -12)))) - (let ((top-w top-weight)) (.mov weight-bcast top-w)) - (let ((lower-w lower-weight)) (.mov vf2 lower-w)) - (.lvf vf3 (&-> sf0 0 quad)) - (.lvf vf4 (&-> sf0 1 quad)) - (.lvf vf5 (&-> sf0 2 quad)) - (.lvf vf6 (&-> sf0 3 quad)) - (.lvf vf7 (&-> sf0 4 quad)) - (.lvf vf8 (&-> sf0 5 quad)) - (.mul.x.vf vf3 vf3 vf2) - (.mul.x.vf vf4 vf4 vf2) - (.mul.x.vf vf5 vf5 vf2) - (.mul.x.vf vf6 vf6 vf2) - (.mul.x.vf vf7 vf7 vf2) - (.mul.x.vf vf8 vf8 vf2) - (.lvf vf9 (&-> sf0 6 quad)) - (.lvf vf10 (&-> sf0 7 quad)) - (.lvf vf11 (&-> sf0 8 quad)) - (.lvf vf12 (&-> sf0 9 quad)) - (.lvf vf13 (&-> sf0 10 quad)) - (.lvf vf14 (&-> sf0 11 quad)) - (.mul.x.vf vf9 vf9 weight-bcast) - (.mul.x.vf vf10 vf10 weight-bcast) - (.mul.x.vf vf11 vf11 weight-bcast) - (.mul.x.vf vf12 vf12 weight-bcast) - (.mul.x.vf vf13 vf13 weight-bcast) - (.mul.x.vf vf14 vf14 weight-bcast) - (.add.vf vf3 vf3 vf9) - (.add.vf vf4 vf4 vf10) - (.add.vf vf5 vf5 vf11) - (.add.vf vf6 vf6 vf12) - (.add.vf vf7 vf7 vf13) - (.add.vf vf8 vf8 vf14) - (.svf (&-> sf0 0 quad) vf3) - (.svf (&-> sf0 1 quad) vf4) - (.svf (&-> sf0 2 quad) vf5) - (.svf (&-> sf0 3 quad) vf6) - (.svf (&-> sf0 4 quad) vf7) - (.svf (&-> sf0 5 quad) vf8) - (set! frame-top (the-as (inline-array vector) (-> sf0 6))))))) - (+! weight-offset 4))) - (let ((upload-index 0)) - (dotimes (channel-index channel-count) - (when (< 0.001 (-> (scratchpad-object terrain-context) work foreground joint-work flatten-array channel-index)) - (let* ((chan (-> control channel channel-index)) - (jacc (-> chan frame-group frames)) - (frame-num (-> chan frame-num)) - (base-frame (the int frame-num)) - (frac-frame (- frame-num (the float base-frame)))) - (let ((last-frame (+ (-> jacc num-frames) -1))) - (if (not (-> chan frame-group)) (format 0 "Channel ~D skel ~A frame-group is #f!!!~%" channel-index control)) - (when (>= base-frame (the-as int last-frame)) - (set! frac-frame 0.0) - (set! base-frame (the-as int last-frame)))) - (let ((up (-> (scratchpad-object terrain-context) work foreground joint-work uploads upload-index))) - (set! (-> up fixed) (-> jacc fixed)) - (set! (-> up fixed-qwc) (the-as int (-> jacc fixed-qwc))) - (set! (-> up frame) (-> jacc data base-frame)) - (set! (-> up frame-qwc) (the-as int (if (= frac-frame 0.0) (-> jacc frame-qwc) (* (-> jacc frame-qwc) 2)))) - (set! (-> up amount) (-> (scratchpad-object terrain-context) work foreground joint-work flatten-array channel-index)) - (set! (-> up interp) frac-frame))) - (+! upload-index 1))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work num-uploads) upload-index)) - (dotimes (i channel-count) - (set! (-> control channel i inspector-amount) - (-> (scratchpad-object terrain-context) work foreground joint-work flatten-array i)))) - 0)) - ;; The following functions are a non-optimized decompressor/blender for animation matrices, intended for when ;; you only need the matrix and don't want to decompress all the joints. @@ -1298,6 +1182,8 @@ ;; CSPACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; these functions set cspace transforms from different sources. + (defmethod reset-and-assign-geo! ((this cspace) (geometry basic)) "Clear this coordinate-space node's hierarchy and controller state and assign its optional geometry." @@ -1318,9 +1204,8 @@ (defun cspace<-cspace! ((destination cspace) (source cspace)) "Copy source's bone transform into destination." - (let ((destination-matrix (-> destination bone transform))) - (matrix-copy! destination-matrix (-> source bone transform)) - destination-matrix)) + (matrix-copy! (-> destination bone transform) (-> source bone transform))) + (defun cspace<-rot-yxy! ((destination cspace) (xform transform)) "Build destination's bone rotation from a Y-X-Y Euler transform and apply its scale." @@ -1362,2083 +1247,69 @@ (let ((input-matrix (matrix-from-control! (-> (scratchpad-object terrain-context) work foreground joint-work joint-stack) (-> space joint) control - 'no-push)) - (destination-matrix (-> space bone transform))) - (matrix-copy! destination-matrix input-matrix) - destination-matrix)) + 'no-push))) + (matrix-copy! (-> space bone transform) input-matrix))) (defun cspace<-matrix-joint! ((space cspace) (input-matrix matrix)) "Copy a matrix joint directly into this coordinate space's bone transform." - (let ((destination-matrix (-> space bone transform))) - (matrix-copy! destination-matrix input-matrix) - destination-matrix)) + (matrix-copy! (-> space bone transform) input-matrix)) (defun cspace<-parented-matrix-joint! ((space cspace) (input-matrix matrix)) "Compose a matrix joint with the parent coordinate space's bone transform." (matrix*! (-> space bone transform) input-matrix (-> space parent bone transform))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Scratchpad frame decoding -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun cspace<-parented-transformq-joint! ((space cspace) (xform transformq)) + "Set a cspace's bone transform according to the parent bone and joint transformq. + This is the standard function for skeletal animation and uses the Maya convention + of not recursively applying scale. We multiply by the inverse of the parent's scale + so plain matrix multiplication does the right thing." + + ;; This function was rewritten in plain GOAL. + (let ((joint-tf (new 'stack-no-clear 'matrix)) + (inv-parent-scale (new 'stack-no-clear 'vector)) + (parent-bone (-> space parent bone))) + + ;; set matrix to rotation + (quaternion->matrix joint-tf (-> xform quat)) + + ;; apply our scale + (scale-matrix! joint-tf (-> xform scale) joint-tf) + + ;; cancel parent's scale + (when (!= (-> parent-bone scale w) 0.0) + (set-vector! inv-parent-scale + (/ 1.0 (-> parent-bone scale x)) + (/ 1.0 (-> parent-bone scale y)) + (/ 1.0 (-> parent-bone scale z)) + 1.0) + (column-scale-matrix! joint-tf inv-parent-scale joint-tf)) + + ;; set trans + (vector-copy! (-> joint-tf vector 3) (-> xform trans)) + (set! (-> joint-tf vector 3 w) 1.0) + + ;; multiply: + (matrix*! (-> space bone transform) + joint-tf + (-> parent-bone transform) + ) + + ;; stash scale so any future child can easily cancel it. + (vector-copy! (-> space bone scale) (-> xform scale)) + (none) + ) + ) -;; calc-animation-from-spr keeps the joint count and stream cursors in saved registers while the -;; component functions run. The three decompression functions share that private register ABI and -;; use computed entries within their assembly bodies, so they are not independent ordinary calls. - -(#when PC_PORT - (def-mips2c cspace<-parented-transformq-joint! (function cspace transformq none))) - -(#unless PC_PORT - (defun cspace<-parented-transformq-joint! ((space cspace) (xform transformq)) - "Build a local matrix from xform, compensate for parent scale when present, and concatenate it - with the parent bone transform." - (rlet ((parent (-> space parent)) - (parent-matrix (-> parent bone transform)) - (bone (-> space bone)) - (bone-matrix (-> bone transform)) - (quat :reg vf5) - (double-quat :reg vf6) - (translation :reg vf15) - (joint-scale :reg vf1) - (row-x :reg vf2) - (row-y :reg vf3) - (row-z :reg vf4) - (parent-x :reg vf7) - (parent-y :reg vf8) - (parent-z :reg vf9) - (parent-t :reg vf10) - (world-x :reg vf11) - (world-y :reg vf12) - (world-z :reg vf13) - (world-t :reg vf14) - (reciprocal-parent-scale :reg vf16) - (packed-reciprocals :class i128) - (one-bits) - (reciprocal-x) - (reciprocal-y) - (reciprocal-z) - (parent-has-scale?)) - (nop!) - (m! one-bits 1.0) - (l.vf quat xform 16) - (l.vf translation xform) - (l.vf joint-scale xform 32) - (l.vf parent-x parent-matrix) - (l.vf parent-y parent-matrix 16) - (l.vf parent-z parent-matrix 32) - (l.vf parent-t parent-matrix 48) - (add.vf double-quat quat quat) - ;; Expand the quaternion into three rotation rows. The outer products supply the cross terms; - ;; adding one to the diagonal completes the standard unit-quaternion matrix. - (add.w.vf.x row-x vf0 quat) - (add.z.vf.y row-x vf0 quat) - (sub.y.vf.z row-x vf0 quat) - (sub.w.vf.w row-x vf0 vf0) - (sub.z.vf.x row-y vf0 quat) - (add.w.vf.y row-y vf0 quat) - (add.x.vf.z row-y vf0 quat) - (sub.w.vf.w row-y vf0 vf0) - (add.y.vf.x row-z vf0 quat) - (sub.x.vf.y row-z vf0 quat) - (add.w.vf.z row-z vf0 quat) - (sub.w.vf.w row-z vf0 vf0) - (outer.product.a.vf acc double-quat row-x) - (outer.product.b.vf row-x row-x double-quat acc) - (outer.product.a.vf acc double-quat row-y) - (outer.product.b.vf row-y row-y double-quat acc) - (outer.product.a.vf acc double-quat row-z) - (outer.product.b.vf row-z row-z double-quat acc) - (add.w.vf.x row-x row-x vf0) - (add.w.vf.y row-y row-y vf0) - (add.w.vf.z row-z row-z vf0) - (mul.x.vf row-x row-x joint-scale) - (mul.y.vf row-y row-y joint-scale) - (mul.z.vf row-z row-z joint-scale) - (l.w parent-has-scale? parent-matrix 76) - (b.z parent-has-scale? compose :delay (div.s reciprocal-z 1.0 (-> parent-matrix data 18))) - ;; A scaled parent records that fact in scale.w. Divide its basis scale out before multiplying - ;; so the child's authored scale is not compounded a second time. - (div.s reciprocal-x 1.0 (-> parent-matrix data 16)) - (div.s reciprocal-y 1.0 (-> parent-matrix data 17)) - (m packed-reciprocals reciprocal-x) - (pextlw packed-reciprocals reciprocal-y packed-reciprocals) - (pcpyld packed-reciprocals reciprocal-z packed-reciprocals) - (m reciprocal-parent-scale packed-reciprocals) - (mul.vf row-x row-x reciprocal-parent-scale) - (mul.vf row-y row-y reciprocal-parent-scale) - (mul.vf row-z row-z reciprocal-parent-scale) - (label compose) - (mula.x.vf parent-x row-x) - (madda.y.vf parent-y row-x) - (madda.z.vf parent-z row-x) - (madd.w.vf world-x parent-t row-x) - (mula.x.vf parent-x row-y) - (madda.y.vf parent-y row-y) - (madda.z.vf parent-z row-y) - (madd.w.vf world-y parent-t row-y) - (mula.x.vf parent-x row-z) - (madda.y.vf parent-y row-z) - (madda.z.vf parent-z row-z) - (madd.w.vf world-z parent-t row-z) - (mula.x.vf parent-x translation) - (madda.y.vf parent-y translation) - (madda.z.vf parent-z translation) - (madd.w.vf world-t parent-t vf0) - (s.vf joint-scale bone 64) - (s.vf world-x bone-matrix) - (s.vf world-y bone-matrix 16) - (s.vf world-z bone-matrix 32) - (jr ra :delay (s.vf world-t bone-matrix 48))))) - -(#unless PC_PORT - (defun clear-frame-accumulator ((destination (inline-array vector))) - "Zero the two matrices and every transformq after them. The joint count arrives in s2 from - calc-animation-from-spr, and the -2 accounts for those two matrices." - (rlet ((cursor destination) - (remaining :reg s2) - (zero :class i128)) - (s.q zero cursor) - (-! remaining 2) - (s.q zero cursor 16) - (nop!) - (s.q zero cursor 32) - (nop!) - (s.q zero cursor 48) - (nop!) - (s.q zero cursor 64) - (nop!) - (s.q zero cursor 80) - (nop!) - (s.q zero cursor 96) - (nop!) - (s.q zero cursor 112) - (&+! cursor 128) - (label clear-transform) - (s.q zero cursor) - (-! remaining 1) - (s.q zero cursor 16) - (&+! cursor 48) - (nop!) - (nop!) - (b.nz remaining clear-transform :delay (s.q zero cursor -16)))) - (defun normalize-frame-quaternions ((destination (inline-array vector))) - "Set trans.w and scale.w back to 1.0 and renormalize every accumulated quaternion. The joint - count is in s2, less the two matrices." - (rlet ((cursor (&+ destination 128)) - (remaining :reg s2) - (translation :reg vf1) - (rotation :reg vf4) - (scale :reg vf7) - (squared :reg vf10)) - (-! remaining 2) - (label normalize-transform) - (l.vf rotation cursor 16) - (l.vf translation cursor) - (l.vf scale cursor 32) - (mul.vf squared rotation rotation) - (move.w.vf translation vf0) - (move.w.vf scale vf0) - (mula.w.vf vf0 squared) - (madda.z.vf vf0 squared) - (madda.y.vf vf0 squared) - (madd.x.vf squared vf0 squared) - (s.vf translation cursor) - (s.vf scale cursor 32) - (&+! cursor 48) - (rsqrt.w.w Q vf0 squared) - (waitq) - (mulq.vf rotation rotation Q) - (-! remaining 1) - (b.nz remaining normalize-transform :delay (s.vf rotation cursor -32)))) - (defun decompress-fixed-data-to-accumulator () - "Add an animation's fixed components to the frame accumulator, weighted. The 64-byte header is - copied to spad first because the control nibbles are read many times, then either fixed matrix, - then one computed jump per transform record." - (declare (asm-func)) - ;; The three decompressors share one private register ABI set up by calc-animation-from-spr, - ;; so these are pinned rather than allocated. frame walks the output accumulator, block is the - ;; compressed source in spad, weight is the blend amount, and hdr is the spad copy of the - ;; fixed block's header. stream64, stream32 and stream16 are the three read cursors. - ;; transforms-left counts down the post-matrix records, controls holds the current packed - ;; control word with nibbles-left nibbles still in it, and control-ptr walks the rest. - ;; vf1 through vf12 carry two names each: matrix rows in the header section, then translation, - ;; quaternion and scale in the per-transform paths. They are the same registers either way. - (rlet ((frame :reg a0) - (block :reg a1 :type joint-anim-compressed-fixed) - (weight :reg a2) - (hdr :reg t1 :type joint-anim-compressed-hdr) - (jump-table :reg t2) - (nibble :reg t3) - (stream64 :reg t4) - (stream32 :reg t5) - (stream16 :reg t6) - (hdr-qw-a :reg t4) ;; borrowed as quadword shuttles for the header copy - (hdr-qw-b :reg t5) - (transforms-left :reg s2) - (nibbles-left :reg s3) - (controls :reg s4) - (control-ptr :reg s5) - (data-base :reg v1) - (pack :reg s6) - (pack-hi :reg gp) - (pack2 :reg t8) - (pack2-hi :reg fp) - (xfer :reg t9) - (mtx-row0 :reg vf1) - (mtx-row1 :reg vf2) - (mtx-row2 :reg vf3) - (mtx-row3 :reg vf4) - (acc-row0 :reg vf9) - (acc-row1 :reg vf10) - (acc-row2 :reg vf11) - (acc-row3 :reg vf12) - (trans :reg vf1) - (trans-b :reg vf2) - (out-trans :reg vf3) - (quat :reg vf4) - (quat-b :reg vf5) - (out-quat :reg vf6) - (scale :reg vf7) - (scale-b :reg vf8) - (out-scale :reg vf9) - (dot :reg vf10) - (weight-vf :reg vf13) - (scales :reg vf14) - (zero-vf :reg vf15)) - (label fixed-entry) - (l.q hdr-qw-a block) - (add.i sp sp -16) - (l.q hdr-qw-b block 16) - (nop!) - (s.q hdr-qw-a hdr) - (nop!) - (s.q hdr-qw-b hdr 16) - (nop!) - (l.q hdr-qw-a block 32) - (nop!) - (l.q hdr-qw-b block 48) - (nop!) - (s.q hdr-qw-a hdr 32) - (nop!) - (s.q hdr-qw-b hdr 48) - (nop!) - (s.q frame sp) - (nop!) - (m weight-vf weight) - (lui jump-table 28672) ;; spad base, 0x70000000 - (l.w stream64 (-> block offset-64)) - (add.i data-base block (offset-of joint-anim-compressed-fixed data)) - (l.w stream32 (-> block offset-32)) - (add control-ptr hdr r0) - (l.w stream16 (-> block offset-16)) - (add stream64 stream64 data-base) - (mul.x.vf weight-vf scales weight-vf) - (add.i jump-table jump-table (joint-spad-offset fix-jmp-table)) - (l.w transforms-left (-> hdr num-joints)) - (add stream32 stream32 data-base) - (l.w controls (-> hdr matrix-bits)) - (add stream16 stream16 data-base) - (add.i nibbles-left r0 8) - (add.i control-ptr control-ptr 4) - (and.i nibble controls 1) - (nop!) - (b.nz nibble fixed-second-matrix :delay (nop!)) - (l.vf mtx-row0 stream64) - (l.vf mtx-row1 stream64 16) - (l.vf mtx-row2 stream64 32) - (l.vf mtx-row3 stream64 48) - (l.vf acc-row0 frame) - (add.i stream64 stream64 64) - (l.vf acc-row1 frame 16) - (nop!) - (l.vf acc-row2 frame 32) - (l.vf acc-row3 frame 48) - (mula.w.vf acc-row0 vf0) - (madd.x.vf acc-row0 mtx-row0 weight-vf) - (mula.w.vf acc-row1 vf0) - (madd.x.vf acc-row1 mtx-row1 weight-vf) - (mula.w.vf acc-row2 vf0) - (madd.x.vf acc-row2 mtx-row2 weight-vf) - (mula.w.vf acc-row3 vf0) - (madd.x.vf acc-row3 mtx-row3 weight-vf) - (s.vf acc-row0 frame) - (s.vf acc-row1 frame 16) - (s.vf acc-row2 frame 32) - (s.vf acc-row3 frame 48) - (label fixed-second-matrix) - (and.i nibble controls 2) - (add.i frame frame 64) - (b.nz nibble fixed-controls :delay (nop!)) - (l.vf mtx-row0 stream64) - (l.vf mtx-row1 stream64 16) - (l.vf mtx-row2 stream64 32) - (l.vf mtx-row3 stream64 48) - (l.vf acc-row0 frame) - (add.i stream64 stream64 64) - (l.vf acc-row1 frame 16) - (nop!) - (l.vf acc-row2 frame 32) - (l.vf acc-row3 frame 48) - (mula.w.vf acc-row0 vf0) - (madd.x.vf acc-row0 mtx-row0 weight-vf) - (mula.w.vf acc-row1 vf0) - (madd.x.vf acc-row1 mtx-row1 weight-vf) - (mula.w.vf acc-row2 vf0) - (madd.x.vf acc-row2 mtx-row2 weight-vf) - (mula.w.vf acc-row3 vf0) - (madd.x.vf acc-row3 mtx-row3 weight-vf) - (s.vf acc-row0 frame) - (s.vf acc-row1 frame 16) - (s.vf acc-row2 frame 32) - (s.vf acc-row3 frame 48) - (label fixed-controls) - (l.w controls control-ptr -4) - (add.i frame frame 64) - (label fixed-dispatch) - (and.i nibble controls 15) - (sra controls controls 4) - (sll nibble nibble 2) - (add.i nibbles-left nibbles-left -1) - (add nibble nibble jump-table) - (add.i transforms-left transforms-left -1) - (l.w nibble nibble) - (nop!) - (nop!) - (nop!) - (jr nibble :delay (nop!)) - (label fixed-next-transform) - (b.z transforms-left fixed-return :delay (add.i frame frame 48)) - (b.nz nibbles-left fixed-dispatch :delay (nop!)) - (l.w controls control-ptr) - (add.i control-ptr control-ptr 4) - (b fixed-dispatch :delay (add.i nibbles-left r0 8)) - ;; control nibble 0: the clear bits, so these components come from the fixed streams - (label fixed-path-trans-quat-scale) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (itof.vf quat quat :fixed 15) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (mul.vf dot quat out-quat) - (m trans pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (itof.vf trans trans) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (m xfer dot) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 fixed-quaternion-ready-0 :delay (sub.vf quat zero-vf quat)) - (label fixed-quaternion-ready-0) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (mula.w.vf out-trans vf0) - (madd.y.vf out-trans trans weight-vf) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (s.vf out-scale frame 32) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 8: the clear bits, so these components come from the fixed streams - (label fixed-path-wide-trans-quat-scale) - (l.d xfer stream64 8) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d pack stream64 -8) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (itof.vf quat quat :fixed 15) - (pcpyld pack pack-hi pack) - (mul.vf dot quat out-quat) - (m trans pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (m xfer dot) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 fixed-quaternion-ready-1 :delay (sub.vf quat zero-vf quat)) - (label fixed-quaternion-ready-1) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (mula.w.vf out-trans vf0) - (madd.x.vf out-trans trans weight-vf) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (s.vf out-scale frame 32) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 1, 9: the clear bits, so these components come from the fixed streams - (label fixed-path-quat-scale) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (itof.vf quat quat :fixed 15) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (mul.vf dot quat out-quat) - (m scale pack2) - (mula.w.vf dot vf0) - (itof.vf scale scale :fixed 12) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (m xfer dot) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 fixed-quaternion-ready-2 :delay (sub.vf quat zero-vf quat)) - (label fixed-quaternion-ready-2) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (s.vf out-quat frame 16) - (s.vf out-scale frame 32) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 2: the clear bits, so these components come from the fixed streams - (label fixed-path-trans-scale) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (itof.vf trans trans) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (mula.w.vf out-trans vf0) - (madd.y.vf out-trans trans weight-vf) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-trans frame) - (s.vf out-scale frame 32) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 10: the clear bits, so these components come from the fixed streams - (label fixed-path-wide-trans-scale) - (l.d pack stream64) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (pcpyld pack pack-hi pack) - (m trans pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (mula.w.vf out-trans vf0) - (madd.x.vf out-trans trans weight-vf) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-trans frame) - (s.vf out-scale frame 32) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 3, 11: the clear bits, so these components come from the fixed streams - (label fixed-path-scale) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-scale frame 32) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 4: the clear bits, so these components come from the fixed streams - (label fixed-path-trans-quat) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (itof.vf quat quat :fixed 15) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (mul.vf dot quat out-quat) - (m trans pack) - (mula.w.vf dot vf0) - (itof.vf trans trans) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (mula.w.vf out-trans vf0) - (madd.y.vf out-trans trans weight-vf) - (m xfer dot) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 fixed-quaternion-ready-3 :delay (sub.vf quat zero-vf quat)) - (label fixed-quaternion-ready-3) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 12: the clear bits, so these components come from the fixed streams - (label fixed-path-wide-trans-quat) - (l.d xfer stream64 8) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d pack stream64 -8) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (itof.vf quat quat :fixed 15) - (pcpyld pack pack-hi pack) - (mul.vf dot quat out-quat) - (m trans pack) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (mula.w.vf out-trans vf0) - (madd.x.vf out-trans trans weight-vf) - (m xfer dot) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 fixed-quaternion-ready-4 :delay (sub.vf quat zero-vf quat)) - (label fixed-quaternion-ready-4) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 5, 13: the clear bits, so these components come from the fixed streams - (label fixed-path-quat) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (itof.vf quat quat :fixed 15) - (mul.vf dot quat out-quat) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (m xfer dot) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 fixed-quaternion-ready-5 :delay (sub.vf quat zero-vf quat)) - (label fixed-quaternion-ready-5) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (s.vf out-quat frame 16) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 6: the clear bits, so these components come from the fixed streams - (label fixed-path-trans) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans pack) - (itof.vf trans trans) - (mula.w.vf out-trans vf0) - (madd.y.vf out-trans trans weight-vf) - (s.vf out-trans frame) - (b fixed-next-transform :delay (nop!)) - ;; control nibble 14: the clear bits, so these components come from the fixed streams - (label fixed-path-wide-trans) - (l.d pack stream64) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (pcpyld pack pack-hi pack) - (m trans pack) - (mula.w.vf out-trans vf0) - (madd.x.vf out-trans trans weight-vf) - (s.vf out-trans frame) - (b fixed-next-transform :delay (nop!)) - (label fixed-return) - (l.q frame sp) - (nop!) - (jr ra :delay (add.i sp sp 16)) - (jr ra :delay (add sp sp r0)) - (nop!) - (nop!) - (nop!))) - (defun decompress-frame-data-to-accumulator () - "Same as decompress-fixed-data-to-accumulator, but for one frame's animated components, so the - control-bit tests are inverted. The header is already in spad from the fixed pass." - (declare (asm-func)) - ;; The three decompressors share one private register ABI set up by calc-animation-from-spr, - ;; so these are pinned rather than allocated. frame walks the output accumulator, block is the - ;; compressed source in spad, weight is the blend amount, and hdr is the spad copy of the - ;; fixed block's header. stream64, stream32 and stream16 are the three read cursors. - ;; transforms-left counts down the post-matrix records, controls holds the current packed - ;; control word with nibbles-left nibbles still in it, and control-ptr walks the rest. - ;; vf1 through vf12 carry two names each: matrix rows in the header section, then translation, - ;; quaternion and scale in the per-transform paths. They are the same registers either way. - (rlet ((frame :reg a0) - (block :reg a1 :type joint-anim-compressed-frame) - (weight :reg a2) - (hdr :reg t1 :type joint-anim-compressed-hdr) - (jump-table :reg t2) - (nibble :reg t3) - (stream64 :reg t4) - (stream32 :reg t5) - (stream16 :reg t6) - (transforms-left :reg s2) - (nibbles-left :reg s3) - (controls :reg s4) - (control-ptr :reg s5) - (data-base :reg v1) - (pack :reg s6) - (pack-hi :reg gp) - (pack2 :reg t8) - (pack2-hi :reg fp) - (xfer :reg t9) - (mtx-row0 :reg vf1) - (mtx-row1 :reg vf2) - (mtx-row2 :reg vf3) - (mtx-row3 :reg vf4) - (acc-row0 :reg vf9) - (acc-row1 :reg vf10) - (acc-row2 :reg vf11) - (acc-row3 :reg vf12) - (trans :reg vf1) - (trans-b :reg vf2) - (out-trans :reg vf3) - (quat :reg vf4) - (quat-b :reg vf5) - (out-quat :reg vf6) - (scale :reg vf7) - (scale-b :reg vf8) - (out-scale :reg vf9) - (dot :reg vf10) - (weight-vf :reg vf13) - (scales :reg vf14) - (zero-vf :reg vf15)) - (label frame-entry) - (add.i sp sp -16) - (m weight-vf weight) - (s.q frame sp) - (lui jump-table 28672) ;; spad base, 0x70000000 - (l.w stream64 (-> block offset-64)) - (add.i data-base block (offset-of joint-anim-compressed-frame data)) - (l.w stream32 (-> block offset-32)) - (add control-ptr hdr r0) - (l.w stream16 (-> block offset-16)) - (add stream64 stream64 data-base) - (mul.x.vf weight-vf scales weight-vf) - (add.i jump-table jump-table (joint-spad-offset frm-jmp-table)) - (l.w transforms-left (-> hdr num-joints)) - (add stream32 stream32 data-base) - (l.w controls (-> hdr matrix-bits)) - (add stream16 stream16 data-base) - (add.i nibbles-left r0 8) - (add.i control-ptr control-ptr 4) - (and.i nibble controls 1) - (nop!) - (b.z nibble frame-second-matrix :delay (nop!)) - (l.vf mtx-row0 stream64) - (l.vf mtx-row1 stream64 16) - (l.vf mtx-row2 stream64 32) - (l.vf mtx-row3 stream64 48) - (l.vf acc-row0 frame) - (add.i stream64 stream64 64) - (l.vf acc-row1 frame 16) - (nop!) - (l.vf acc-row2 frame 32) - (l.vf acc-row3 frame 48) - (mula.w.vf acc-row0 vf0) - (madd.x.vf acc-row0 mtx-row0 weight-vf) - (mula.w.vf acc-row1 vf0) - (madd.x.vf acc-row1 mtx-row1 weight-vf) - (mula.w.vf acc-row2 vf0) - (madd.x.vf acc-row2 mtx-row2 weight-vf) - (mula.w.vf acc-row3 vf0) - (madd.x.vf acc-row3 mtx-row3 weight-vf) - (s.vf acc-row0 frame) - (s.vf acc-row1 frame 16) - (s.vf acc-row2 frame 32) - (s.vf acc-row3 frame 48) - (label frame-second-matrix) - (and.i nibble controls 2) - (add.i frame frame 64) - (b.z nibble frame-controls :delay (nop!)) - (l.vf mtx-row0 stream64) - (l.vf mtx-row1 stream64 16) - (l.vf mtx-row2 stream64 32) - (l.vf mtx-row3 stream64 48) - (l.vf acc-row0 frame) - (add.i stream64 stream64 64) - (l.vf acc-row1 frame 16) - (nop!) - (l.vf acc-row2 frame 32) - (l.vf acc-row3 frame 48) - (mula.w.vf acc-row0 vf0) - (madd.x.vf acc-row0 mtx-row0 weight-vf) - (mula.w.vf acc-row1 vf0) - (madd.x.vf acc-row1 mtx-row1 weight-vf) - (mula.w.vf acc-row2 vf0) - (madd.x.vf acc-row2 mtx-row2 weight-vf) - (mula.w.vf acc-row3 vf0) - (madd.x.vf acc-row3 mtx-row3 weight-vf) - (s.vf acc-row0 frame) - (s.vf acc-row1 frame 16) - (s.vf acc-row2 frame 32) - (s.vf acc-row3 frame 48) - (label frame-controls) - (l.w controls control-ptr -4) - (add.i frame frame 64) - (label frame-dispatch) - (and.i nibble controls 15) - (sra controls controls 4) - (sll nibble nibble 2) - (add.i nibbles-left nibbles-left -1) - (add nibble nibble jump-table) - (add.i transforms-left transforms-left -1) - (l.w nibble nibble) - (nop!) - (nop!) - (nop!) - (jr nibble :delay (nop!)) - (label frame-next-transform) - (b.z transforms-left frame-return :delay (add.i frame frame 48)) - (b.nz nibbles-left frame-dispatch :delay (nop!)) - (l.w controls control-ptr) - (add.i control-ptr control-ptr 4) - (b frame-dispatch :delay (add.i nibbles-left r0 8)) - ;; control nibble 1: the set bits, so these components come from this frame - (label frame-path-trans) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans pack) - (itof.vf trans trans) - (mula.w.vf out-trans vf0) - (madd.y.vf out-trans trans weight-vf) - (s.vf out-trans frame) - (b frame-next-transform :delay (nop!)) - ;; control nibble 9: the set bits, so these components come from this frame - (label frame-path-wide-trans) - (l.d pack stream64) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (pcpyld pack pack-hi pack) - (m trans pack) - (mula.w.vf out-trans vf0) - (madd.x.vf out-trans trans weight-vf) - (s.vf out-trans frame) - (b frame-next-transform :delay (nop!)) - ;; control nibble 2, 10: the set bits, so these components come from this frame - (label frame-path-quat) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (itof.vf quat quat :fixed 15) - (mul.vf dot quat out-quat) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (m xfer dot) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 frame-quaternion-ready-0 :delay (sub.vf quat zero-vf quat)) - (label frame-quaternion-ready-0) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (s.vf out-quat frame 16) - (b frame-next-transform :delay (nop!)) - ;; control nibble 3: the set bits, so these components come from this frame - (label frame-path-quat-trans) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (itof.vf quat quat :fixed 15) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (mul.vf dot quat out-quat) - (m trans pack) - (mula.w.vf dot vf0) - (itof.vf trans trans) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (mula.w.vf out-trans vf0) - (madd.y.vf out-trans trans weight-vf) - (m xfer dot) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 frame-quaternion-ready-1 :delay (sub.vf quat zero-vf quat)) - (label frame-quaternion-ready-1) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (b frame-next-transform :delay (nop!)) - ;; control nibble 11: the set bits, so these components come from this frame - (label frame-path-quat-wide-trans) - (l.d xfer stream64 8) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d pack stream64 -8) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (itof.vf quat quat :fixed 15) - (pcpyld pack pack-hi pack) - (mul.vf dot quat out-quat) - (m trans pack) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (mula.w.vf out-trans vf0) - (madd.x.vf out-trans trans weight-vf) - (m xfer dot) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 frame-quaternion-ready-2 :delay (sub.vf quat zero-vf quat)) - (label frame-quaternion-ready-2) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (b frame-next-transform :delay (nop!)) - ;; control nibble 4, 12: the set bits, so these components come from this frame - (label frame-path-scale) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-scale frame 32) - (b frame-next-transform :delay (nop!)) - ;; control nibble 5: the set bits, so these components come from this frame - (label frame-path-trans-scale) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (itof.vf trans trans) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (mula.w.vf out-trans vf0) - (madd.y.vf out-trans trans weight-vf) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-trans frame) - (s.vf out-scale frame 32) - (b frame-next-transform :delay (nop!)) - ;; control nibble 13: the set bits, so these components come from this frame - (label frame-path-wide-trans-scale) - (l.d pack stream64) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (pcpyld pack pack-hi pack) - (m trans pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (mula.w.vf out-trans vf0) - (madd.x.vf out-trans trans weight-vf) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-trans frame) - (s.vf out-scale frame 32) - (b frame-next-transform :delay (nop!)) - ;; control nibble 6, 14: the set bits, so these components come from this frame - (label frame-path-quat-scale) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (itof.vf quat quat :fixed 15) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (mul.vf dot quat out-quat) - (m scale pack2) - (mula.w.vf dot vf0) - (itof.vf scale scale :fixed 12) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (m xfer dot) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 frame-quaternion-ready-3 :delay (sub.vf quat zero-vf quat)) - (label frame-quaternion-ready-3) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (s.vf out-quat frame 16) - (s.vf out-scale frame 32) - (b frame-next-transform :delay (nop!)) - ;; control nibble 7: the set bits, so these components come from this frame - (label frame-path-quat-trans-scale) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (itof.vf quat quat :fixed 15) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (mul.vf dot quat out-quat) - (m trans pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (itof.vf trans trans) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (m xfer dot) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 frame-quaternion-ready-4 :delay (sub.vf quat zero-vf quat)) - (label frame-quaternion-ready-4) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (mula.w.vf out-trans vf0) - (madd.y.vf out-trans trans weight-vf) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (s.vf out-scale frame 32) - (b frame-next-transform :delay (nop!)) - ;; control nibble 15: the set bits, so these components come from this frame - (label frame-path-quat-wide-trans-scale) - (l.d xfer stream64 8) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d pack stream64 -8) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (itof.vf quat quat :fixed 15) - (pcpyld pack pack-hi pack) - (mul.vf dot quat out-quat) - (m trans pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (m xfer dot) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 frame-quaternion-ready-5 :delay (sub.vf quat zero-vf quat)) - (label frame-quaternion-ready-5) - (itof.vf scale scale :fixed 12) - (mula.w.vf out-quat vf0) - (madd.x.vf out-quat quat weight-vf) - (mula.w.vf out-trans vf0) - (madd.x.vf out-trans trans weight-vf) - (mula.w.vf out-scale vf0) - (madd.x.vf out-scale scale weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (s.vf out-scale frame 32) - (b frame-next-transform :delay (nop!)) - (label frame-return) - (l.q frame sp) - (nop!) - (jr ra :delay (add.i sp sp 16)) - (jr ra :delay (add sp sp r0)) - (nop!) - (nop!) - (nop!))) - (defun decompress-frame-data-pair-to-accumulator () - "Decode two adjacent frames at once. Every present component is read from both, blended with - interp and 1 - interp, and added once. After the setup weight-vf carries both halves, x and w - holding the pair weights and y and z the compact-translation factor. Only the first frame's - quaternion is hemisphere-checked; the second rides along with it." - (declare (asm-func)) - ;; The three decompressors share one private register ABI set up by calc-animation-from-spr, - ;; so these are pinned rather than allocated. frame walks the output accumulator, block is the - ;; compressed source in spad, weight is the blend amount, and hdr is the spad copy of the - ;; fixed block's header. stream64, stream32 and stream16 are the three read cursors. - ;; transforms-left counts down the post-matrix records, controls holds the current packed - ;; control word with nibbles-left nibbles still in it, and control-ptr walks the rest. - ;; vf1 through vf12 carry two names each: matrix rows in the header section, then translation, - ;; quaternion and scale in the per-transform paths. They are the same registers either way. - (rlet ((frame :reg a0) - (block :reg a1 :type joint-anim-compressed-frame) - (weight :reg a2) - (second-block :reg a3 :type joint-anim-compressed-frame) - (interp :reg t0) - (hdr :reg t1 :type joint-anim-compressed-hdr) - (jump-table :reg t2) - (nibble :reg t3) - (stream64 :reg t4) - (stream32 :reg t5) - (stream16 :reg t6) - (stream64-b :reg t7) - (stream32-b :reg s0) - (stream16-b :reg s1) - (transforms-left :reg s2) - (nibbles-left :reg s3) - (controls :reg s4) - (control-ptr :reg s5) - (data-base :reg v1) - (pack :reg s6) - (pack-hi :reg gp) - (pack2 :reg t8) - (pack2-hi :reg fp) - (xfer :reg t9) - (mtx-row0 :reg vf1) - (mtx-row1 :reg vf2) - (mtx-row2 :reg vf3) - (mtx-row3 :reg vf4) - (acc-row0 :reg vf9) - (acc-row1 :reg vf10) - (acc-row2 :reg vf11) - (acc-row3 :reg vf12) - (trans :reg vf1) - (trans-b :reg vf2) - (out-trans :reg vf3) - (quat :reg vf4) - (quat-b :reg vf5) - (out-quat :reg vf6) - (scale :reg vf7) - (scale-b :reg vf8) - (out-scale :reg vf9) - (dot :reg vf10) - (mtx2-row0 :reg vf5) - (mtx2-row1 :reg vf6) - (mtx2-row2 :reg vf7) - (mtx2-row3 :reg vf8) - (interp-vf :reg vf11) - (weight-vf :reg vf13) - (scales :reg vf14) - (zero-vf :reg vf15)) - (label pair-entry) - (add.i sp sp -64) - (s.q frame sp) - (s.q stream64-b sp 16) - (s.q stream32-b sp 32) - (s.q stream16-b sp 48) - (m interp-vf interp) - (add second-block second-block block) - (m weight-vf weight) - (lui jump-table 28672) ;; spad base, 0x70000000 - (l.w stream64 (-> block offset-64)) - (add.i data-base block (offset-of joint-anim-compressed-frame data)) - (l.w stream32 (-> block offset-32)) - (add control-ptr hdr r0) - (l.w stream16 (-> block offset-16)) - (add stream64 stream64 data-base) - (sub.x.vf.w interp-vf vf0 interp-vf) - (l.w stream64-b (-> second-block offset-64)) - (mul.x.vf weight-vf scales weight-vf) - (add.i jump-table jump-table (joint-spad-offset pair-jmp-table)) - (l.w transforms-left (-> hdr num-joints)) - (add stream32 stream32 data-base) - (l.w controls (-> hdr matrix-bits)) - (add stream16 stream16 data-base) - (add.i nibbles-left r0 8) - (add.i control-ptr control-ptr 4) - (mul.w.vf.xy weight-vf weight-vf interp-vf) - (l.w stream32-b (-> second-block offset-32)) - (mul.x.vf.zw weight-vf weight-vf interp-vf) - (l.w stream16-b (-> second-block offset-16)) - (nop!) - (add.i data-base second-block (offset-of joint-anim-compressed-frame data)) - (add stream64-b stream64-b data-base) - (add stream32-b stream32-b data-base) - (add stream16-b stream16-b data-base) - (nop!) - (and.i nibble controls 1) - (nop!) - (b.z nibble pair-second-matrix :delay (nop!)) - (l.vf mtx-row0 stream64) - (l.vf mtx-row1 stream64 16) - (l.vf mtx-row2 stream64 32) - (l.vf mtx-row3 stream64 48) - (l.vf mtx2-row0 stream64-b) - (l.vf mtx2-row1 stream64-b 16) - (l.vf mtx2-row2 stream64-b 32) - (l.vf mtx2-row3 stream64-b 48) - (l.vf acc-row0 frame) - (add.i stream64 stream64 64) - (l.vf acc-row1 frame 16) - (add.i stream64-b stream64-b 64) - (l.vf interp-vf frame 32) - (l.vf acc-row3 frame 48) - (mula.w.vf acc-row0 vf0) - (madda.x.vf mtx-row0 weight-vf) - (madd.w.vf acc-row0 mtx2-row0 weight-vf) - (mula.w.vf acc-row1 vf0) - (madda.x.vf mtx-row1 weight-vf) - (madd.w.vf acc-row1 mtx2-row1 weight-vf) - (mula.w.vf interp-vf vf0) - (madda.x.vf mtx-row2 weight-vf) - (madd.w.vf interp-vf mtx2-row2 weight-vf) - (mula.w.vf acc-row3 vf0) - (madda.x.vf mtx-row3 weight-vf) - (madd.w.vf acc-row3 mtx2-row3 weight-vf) - (s.vf acc-row0 frame) - (s.vf acc-row1 frame 16) - (s.vf interp-vf frame 32) - (s.vf acc-row3 frame 48) - (label pair-second-matrix) - (and.i nibble controls 2) - (add.i frame frame 64) - (b.z nibble pair-controls :delay (nop!)) - (l.vf mtx-row0 stream64) - (l.vf mtx-row1 stream64 16) - (l.vf mtx-row2 stream64 32) - (l.vf mtx-row3 stream64 48) - (l.vf mtx2-row0 stream64-b) - (l.vf mtx2-row1 stream64-b 16) - (l.vf mtx2-row2 stream64-b 32) - (l.vf mtx2-row3 stream64-b 48) - (l.vf acc-row0 frame) - (add.i stream64 stream64 64) - (l.vf acc-row1 frame 16) - (add.i stream64-b stream64-b 64) - (l.vf interp-vf frame 32) - (l.vf acc-row3 frame 48) - (mula.w.vf acc-row0 vf0) - (madda.x.vf mtx-row0 weight-vf) - (madd.w.vf acc-row0 mtx2-row0 weight-vf) - (mula.w.vf acc-row1 vf0) - (madda.x.vf mtx-row1 weight-vf) - (madd.w.vf acc-row1 mtx2-row1 weight-vf) - (mula.w.vf interp-vf vf0) - (madda.x.vf mtx-row2 weight-vf) - (madd.w.vf interp-vf mtx2-row2 weight-vf) - (mula.w.vf acc-row3 vf0) - (madda.x.vf mtx-row3 weight-vf) - (madd.w.vf acc-row3 mtx2-row3 weight-vf) - (s.vf acc-row0 frame) - (s.vf acc-row1 frame 16) - (s.vf interp-vf frame 32) - (s.vf acc-row3 frame 48) - (label pair-controls) - (l.w controls control-ptr -4) - (add.i frame frame 64) - (label pair-dispatch) - (and.i nibble controls 15) - (sra controls controls 4) - (sll nibble nibble 2) - (add.i nibbles-left nibbles-left -1) - (add nibble nibble jump-table) - (add.i transforms-left transforms-left -1) - (l.w nibble nibble) - (nop!) - (nop!) - (nop!) - (jr nibble :delay (nop!)) - (label pair-next-transform) - (b.z transforms-left pair-return :delay (add.i frame frame 48)) - (b.nz nibbles-left pair-dispatch :delay (nop!)) - (l.w controls control-ptr) - (add.i control-ptr control-ptr 4) - (b pair-dispatch :delay (add.i nibbles-left r0 8)) - ;; control nibble 1: the set bits, decoded from both frames and blended - (label pair-path-trans) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans pack) - (l.w pack stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack-hi stream16-b) - (add.i stream16-b stream16-b 2) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans-b pack) - (itof.vf trans trans) - (itof.vf trans-b trans-b) - (mula.w.vf out-trans vf0) - (madda.y.vf trans weight-vf) - (madd.z.vf out-trans trans-b weight-vf) - (s.vf out-trans frame) - (b pair-next-transform :delay (nop!)) - ;; control nibble 9: the set bits, decoded from both frames and blended - (label pair-path-wide-trans) - (l.d pack stream64) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (pcpyld pack pack-hi pack) - (m trans pack) - (l.d pack stream64-b) - (add.i stream64-b stream64-b 8) - (l.w pack-hi stream32-b) - (add.i stream32-b stream32-b 4) - (pcpyld pack pack-hi pack) - (m trans-b pack) - (mula.w.vf out-trans vf0) - (madda.x.vf trans weight-vf) - (madd.w.vf out-trans trans-b weight-vf) - (s.vf out-trans frame) - (b pair-next-transform :delay (nop!)) - ;; control nibble 2, 10: the set bits, decoded from both frames and blended - (label pair-path-quat) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d xfer stream64-b) - (add.i stream64-b stream64-b 8) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat-b xfer) - (itof.vf quat quat :fixed 15) - (itof.vf quat-b quat-b :fixed 15) - (mula.x.vf quat weight-vf) - (madd.w.vf quat quat-b weight-vf) - (mul.vf dot quat out-quat) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (m xfer dot) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 pair-quaternion-ready-0 :delay (sub.vf quat zero-vf quat)) - (label pair-quaternion-ready-0) - (add.vf out-quat out-quat quat) - (s.vf out-quat frame 16) - (b pair-next-transform :delay (nop!)) - ;; control nibble 3: the set bits, decoded from both frames and blended - (label pair-path-quat-trans) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d xfer stream64-b) - (add.i stream64-b stream64-b 8) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat-b xfer) - (itof.vf quat quat :fixed 15) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (itof.vf quat-b quat-b :fixed 15) - (l.vf out-trans frame) - (pextlw pack pack-hi pack) - (mula.x.vf quat weight-vf) - (madd.w.vf quat quat-b weight-vf) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans pack) - (mul.vf dot quat out-quat) - (l.w pack stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack-hi stream16-b) - (add.i stream16-b stream16-b 2) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m xfer dot) - (m trans-b pack) - (itof.vf trans trans) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 pair-quaternion-ready-1 :delay (sub.vf quat zero-vf quat)) - (label pair-quaternion-ready-1) - (itof.vf trans-b trans-b) - (add.vf out-quat out-quat quat) - (mula.w.vf out-trans vf0) - (madda.y.vf trans weight-vf) - (madd.z.vf out-trans trans-b weight-vf) - (s.vf out-quat frame 16) - (s.vf out-trans frame) - (b pair-next-transform :delay (nop!)) - ;; control nibble 11: the set bits, decoded from both frames and blended - (label pair-path-quat-wide-trans) - (l.d xfer stream64 8) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d xfer stream64-b 8) - (add.i stream64-b stream64-b 8) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat-b xfer) - (itof.vf quat quat :fixed 15) - (l.d pack stream64 -8) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (itof.vf quat-b quat-b :fixed 15) - (l.vf out-trans frame) - (pcpyld pack pack-hi pack) - (mula.x.vf quat weight-vf) - (madd.w.vf quat quat-b weight-vf) - (m trans pack) - (mul.vf dot quat out-quat) - (l.d pack stream64-b -8) - (add.i stream64-b stream64-b 8) - (l.w pack-hi stream32-b) - (add.i stream32-b stream32-b 4) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (pcpyld pack pack-hi pack) - (m xfer dot) - (m trans-b pack) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 pair-quaternion-ready-2 :delay (sub.vf quat zero-vf quat)) - (label pair-quaternion-ready-2) - (add.vf out-quat out-quat quat) - (mula.w.vf out-trans vf0) - (madda.x.vf trans weight-vf) - (madd.w.vf out-trans trans-b weight-vf) - (s.vf out-quat frame 16) - (s.vf out-trans frame) - (b pair-next-transform :delay (nop!)) - ;; control nibble 4, 12: the set bits, decoded from both frames and blended - (label pair-path-scale) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (l.w pack2 stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack2-hi stream16-b) - (add.i stream16-b stream16-b 2) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale-b pack2) - (itof.vf scale scale :fixed 12) - (itof.vf scale-b scale-b :fixed 12) - (mula.w.vf out-scale vf0) - (madda.x.vf scale weight-vf) - (madd.w.vf out-scale scale-b weight-vf) - (s.vf out-scale frame 32) - (b pair-next-transform :delay (nop!)) - ;; control nibble 5: the set bits, decoded from both frames and blended - (label pair-path-trans-scale) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-trans frame) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans pack) - (l.w pack stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack-hi stream16-b) - (add.i stream16-b stream16-b 2) - (pextlw pack pack-hi pack) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans-b pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (itof.vf trans trans) - (itof.vf trans-b trans-b) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (mula.w.vf out-trans vf0) - (madda.y.vf trans weight-vf) - (madd.z.vf out-trans trans-b weight-vf) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (l.w pack2 stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack2-hi stream16-b) - (add.i stream16-b stream16-b 2) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale-b pack2) - (itof.vf scale scale :fixed 12) - (itof.vf scale-b scale-b :fixed 12) - (mula.w.vf out-scale vf0) - (madda.x.vf scale weight-vf) - (madd.w.vf out-scale scale-b weight-vf) - (s.vf out-trans frame) - (s.vf out-scale frame 32) - (b pair-next-transform :delay (nop!)) - ;; control nibble 13: the set bits, decoded from both frames and blended - (label pair-path-wide-trans-scale) - (l.d pack stream64) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (l.vf out-trans frame) - (pcpyld pack pack-hi pack) - (m trans pack) - (l.d pack stream64-b) - (add.i stream64-b stream64-b 8) - (l.w pack-hi stream32-b) - (add.i stream32-b stream32-b 4) - (pcpyld pack pack-hi pack) - (m trans-b pack) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (mula.w.vf out-trans vf0) - (madda.x.vf trans weight-vf) - (madd.w.vf out-trans trans-b weight-vf) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (l.w pack2 stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack2-hi stream16-b) - (add.i stream16-b stream16-b 2) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale-b pack2) - (itof.vf scale scale :fixed 12) - (itof.vf scale-b scale-b :fixed 12) - (mula.w.vf out-scale vf0) - (madda.x.vf scale weight-vf) - (madd.w.vf out-scale scale-b weight-vf) - (s.vf out-trans frame) - (s.vf out-scale frame 32) - (b pair-next-transform :delay (nop!)) - ;; control nibble 6, 14: the set bits, decoded from both frames and blended - (label pair-path-quat-scale) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d xfer stream64-b) - (add.i stream64-b stream64-b 8) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat-b xfer) - (itof.vf quat quat :fixed 15) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (itof.vf quat-b quat-b :fixed 15) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (mula.x.vf quat weight-vf) - (madd.w.vf quat quat-b weight-vf) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (mul.vf dot quat out-quat) - (l.w pack2 stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack2-hi stream16-b) - (add.i stream16-b stream16-b 2) - (pextlw pack2 pack2-hi pack2) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale-b pack2) - (m xfer dot) - (itof.vf scale scale :fixed 12) - (itof.vf scale-b scale-b :fixed 12) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 pair-quaternion-ready-3 :delay (sub.vf quat zero-vf quat)) - (label pair-quaternion-ready-3) - (mula.w.vf out-scale vf0) - (madda.x.vf scale weight-vf) - (madd.w.vf out-scale scale-b weight-vf) - (add.vf out-quat out-quat quat) - (s.vf out-quat frame 16) - (s.vf out-scale frame 32) - (b pair-next-transform :delay (nop!)) - ;; control nibble 7: the set bits, decoded from both frames and blended - (label pair-path-quat-trans-scale) - (l.d xfer stream64) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d xfer stream64-b) - (add.i stream64-b stream64-b 8) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat-b xfer) - (l.w pack stream32) - (add.i stream32 stream32 4) - (l.h pack-hi stream16) - (add.i stream16 stream16 2) - (itof.vf quat quat :fixed 15) - (itof.vf quat-b quat-b :fixed 15) - (l.vf out-trans frame) - (pextlw pack pack-hi pack) - (mula.x.vf quat weight-vf) - (madd.w.vf quat quat-b weight-vf) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans pack) - (mul.vf dot quat out-quat) - (l.w pack stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack-hi stream16-b) - (add.i stream16-b stream16-b 2) - (pextlw pack pack-hi pack) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (pextlh pack pack r0) - (sra.w pack pack 16) - (m trans-b pack) - (m xfer dot) - (itof.vf trans trans) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 pair-quaternion-ready-4 :delay (sub.vf quat zero-vf quat)) - (label pair-quaternion-ready-4) - (itof.vf trans-b trans-b) - (mula.w.vf out-trans vf0) - (madda.y.vf trans weight-vf) - (madd.z.vf out-trans trans-b weight-vf) - (add.vf out-quat out-quat quat) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (l.w pack2 stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack2-hi stream16-b) - (add.i stream16-b stream16-b 2) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale-b pack2) - (itof.vf scale scale :fixed 12) - (itof.vf scale-b scale-b :fixed 12) - (mula.w.vf out-scale vf0) - (madda.x.vf scale weight-vf) - (madd.w.vf out-scale scale-b weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (s.vf out-scale frame 32) - (b pair-next-transform :delay (nop!)) - ;; control nibble 15: the set bits, decoded from both frames and blended - (label pair-path-quat-wide-trans-scale) - (l.d xfer stream64 8) - (add.i stream64 stream64 8) - (l.vf out-quat frame 16) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat xfer) - (l.d xfer stream64-b 8) - (add.i stream64-b stream64-b 8) - (pextlh xfer xfer r0) - (sra.w xfer xfer 16) - (m quat-b xfer) - (l.d pack stream64 -8) - (add.i stream64 stream64 8) - (l.w pack-hi stream32) - (add.i stream32 stream32 4) - (itof.vf quat quat :fixed 15) - (itof.vf quat-b quat-b :fixed 15) - (l.vf out-trans frame) - (pcpyld pack pack-hi pack) - (mula.x.vf quat weight-vf) - (madd.w.vf quat quat-b weight-vf) - (m trans pack) - (mul.vf dot quat out-quat) - (l.d pack stream64-b -8) - (add.i stream64-b stream64-b 8) - (l.w pack-hi stream32-b) - (add.i stream32-b stream32-b 4) - (pcpyld pack pack-hi pack) - (mula.w.vf dot vf0) - (madda.z.vf vf0 dot) - (madda.y.vf vf0 dot) - (madd.x.vf dot vf0 dot) - (m trans-b pack) - (m xfer dot) - (l.w pack2 stream32) - (add.i stream32 stream32 4) - (l.h pack2-hi stream16) - (add.i stream16 stream16 2) - (pcpyud xfer xfer r0) - (b.ltl xfer r0 pair-quaternion-ready-5 :delay (sub.vf quat zero-vf quat)) - (label pair-quaternion-ready-5) - (mula.w.vf out-trans vf0) - (madda.x.vf trans weight-vf) - (madd.w.vf out-trans trans-b weight-vf) - (add.vf out-quat out-quat quat) - (l.vf out-scale frame 32) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale pack2) - (l.w pack2 stream32-b) - (add.i stream32-b stream32-b 4) - (l.h pack2-hi stream16-b) - (add.i stream16-b stream16-b 2) - (pextlw pack2 pack2-hi pack2) - (pextlh pack2 pack2 r0) - (sra.w pack2 pack2 16) - (m scale-b pack2) - (itof.vf scale scale :fixed 12) - (itof.vf scale-b scale-b :fixed 12) - (mula.w.vf out-scale vf0) - (madda.x.vf scale weight-vf) - (madd.w.vf out-scale scale-b weight-vf) - (s.vf out-trans frame) - (s.vf out-quat frame 16) - (s.vf out-scale frame 32) - (b pair-next-transform :delay (nop!)) - (label pair-return) - (l.q frame sp) - (l.q stream64-b sp 16) - (l.q stream32-b sp 32) - (l.q stream16-b sp 48) - (jr ra :delay (add.i sp sp 64)) - (jr ra :delay (add sp sp r0)) - (nop!) - (nop!)))) - -(#when PC_PORT - (define-extern decompress-fixed-data-to-accumulator (function none)) - (define-extern decompress-frame-data-to-accumulator (function none)) - (define-extern decompress-frame-data-pair-to-accumulator (function none))) - -(defun make-joint-jump-tables () - "Install the 16 control-nibble destinations for each of the three decompressors, in spad. - Indexing on the whole nibble lets a transform with no scale skip the scale code entirely - instead of testing for it." - ;; The numbers are instruction offsets into each assembly function, so they only mean anything - ;; against that function's own instruction stream; the (label *-path-*) names in the - ;; decompressors sit at exactly these offsets. fix-jmp-table takes the clear bits, meaning the - ;; components present in the fixed streams: - ;; 0 -> trans-quat-scale 8 -> wide-trans-quat-scale - ;; 1 -> quat-scale 9 -> quat-scale (bit 3 is meaningless with no trans) - ;; 2 -> trans-scale 10 -> wide-trans-scale - ;; 3 -> scale 11 -> scale - ;; 4 -> trans-quat 12 -> wide-trans-quat - ;; 5 -> quat 13 -> quat - ;; 6 -> trans 14 -> wide-trans - ;; 7 -> nothing 15 -> nothing (straight to fixed-next-transform) - ;; frm-jmp-table and pair-jmp-table take the set bits, so their tables are the same list read - ;; the other way round: 0 and 8 are the nothing case and 15 is all three with wide translation. - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 0) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 108 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 1) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 2) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 233 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 3) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 4) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 301 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 5) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 6) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 387 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 7) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 8) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 155 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 9) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 199 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 10) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 261 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 11) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 286 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 12) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 335 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 13) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 366 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 14) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 402 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work fix-jmp-table 15) - (the-as (function none) (+ (the-as uint decompress-fixed-data-to-accumulator) (* 100 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 0) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 1) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 92 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 2) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 3) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 140 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 4) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 5) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 220 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 6) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 7) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 307 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 8) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 84 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 9) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 107 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 10) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 119 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 11) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 174 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 12) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 205 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 13) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 248 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 14) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 273 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work frm-jmp-table 15) - (the-as (function none) (+ (the-as uint decompress-frame-data-to-accumulator) (* 354 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 0) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 1) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 125 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 2) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 3) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 197 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 4) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 5) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 318 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 6) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 7) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 459 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 8) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 117 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 9) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 150 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 10) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 169 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 11) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 248 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 12) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 293 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 13) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 366 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 14) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 408 4)))) - (set! (-> (scratchpad-object terrain-context) work foreground joint-work pair-jmp-table 15) - (the-as (function none) (+ (the-as uint decompress-frame-data-pair-to-accumulator) (* 533 4)))) - 0) - -(#when PC_PORT - (def-mips2c calc-animation-from-spr (function (inline-array vector) int none))) - -(#unless PC_PORT - (defun calc-animation-from-spr ((destination (inline-array vector)) (joint-count int)) - "Run the upload list that flatten-joint-control-to-spr left in spad: clear the frame, then DMA - and accumulate each animation's fixed and frame data, then renormalize. Every DMA is started one - step ahead of the code that consumes it." - (declare (asm-func object) (allow-saved-regs)) - (rlet ((to-spr-channel :reg s0 :type dma-bank-spr) - (uploads-left :reg s1) - (saved-joint-count :reg s2) - (upload :reg t7) - (control-copy :reg t1) - (dma-address :reg t2) - (scratchpad-address :reg t3) - (quadword-count :reg t4) - (dma-control :reg v1) - (interpolation :reg t0) - (weight :reg a2) - (frame-data :reg a1) - (second-frame-offset :reg a3) - (zero :reg vf15) - (one :reg vf14)) - (m! saved-joint-count joint-count) - (m! uploads-left (-> (scratchpad-object terrain-context) work foreground joint-work num-uploads)) - (m! upload (-> (scratchpad-object terrain-context) work foreground joint-work uploads)) - (m! control-copy (&+ (scratchpad-object terrain-context) (joint-spad-offset jacp-hdr))) - ;; SPR_TO_BANK. This moves main memory into spad, so it is the toSPR channel. - (m! to-spr-channel #x1000d400) - ;; one is the broadcast scale vector that the decompressors multiply the blend weight by. - ;; All four lanes start at 1, then two doublings of y and z leave (1, 4, 4, 1). The 4 is the - ;; compact translation's fixed-point factor, carried here rather than in the tables. - (m zero r0) - (b.z uploads-left animation-complete :delay (add.w.vf one zero vf0)) - (label next-upload) - ;; Start the fixed block's DMA into spad and run clear-frame-accumulator underneath it. Both - ;; sync.l are needed, since the qwc and madr stores must be visible before str goes on. - (l.w dma-address upload) - (m! scratchpad-address (joint-spad-offset fixed-data)) - (l.w quadword-count upload (offset-of channel-upload-info fixed-qwc)) - (m! dma-control DMA-CHCR-STR) - (s.w dma-address (-> to-spr-channel madr)) - (s.w scratchpad-address (-> to-spr-channel sadr)) - (nop!) - (s.w quadword-count (-> to-spr-channel qwc)) - (sync.l) - (s.w dma-control (-> to-spr-channel chcr)) - (sync.l) - (add.yz.vf one one one) - (m! saved-joint-count joint-count) - (jalr ra clear-frame-accumulator :delay (add.yz.vf one one one)) - (label wait-fixed) - (l.w dma-control (-> to-spr-channel chcr)) - (nop!) - (and.i dma-control dma-control DMA-CHCR-STR) - (nop!) - (nop!) - (nop!) - (b.nz dma-control wait-fixed :delay (nop!)) - ;; Queue the first frame, then work through the fixed block while that DMA runs. - (l.w dma-address upload (offset-of channel-upload-info frame)) - (m! scratchpad-address (joint-spad-offset frame-data)) - (l.w quadword-count upload (offset-of channel-upload-info frame-qwc)) - (m! dma-control DMA-CHCR-STR) - (s.w dma-address (-> to-spr-channel madr)) - (nop!) - (s.w scratchpad-address (-> to-spr-channel sadr)) - (nop!) - (s.w quadword-count (-> to-spr-channel qwc)) - (sync.l) - (s.w dma-control (-> to-spr-channel chcr)) - (sync.l) - (l.w weight upload (offset-of channel-upload-info amount)) - (m! frame-data (&+ (scratchpad-object terrain-context) (joint-spad-offset fixed-data))) - (-! uploads-left 1) - (jalr ra decompress-fixed-data-to-accumulator :delay (nop!)) - (label wait-frame) - (l.w dma-control (-> to-spr-channel chcr)) - (nop!) - (and.i dma-control dma-control DMA-CHCR-STR) - (nop!) - (nop!) - (nop!) - (b.nz dma-control wait-frame :delay (nop!)) - ;; If requests remain, start the next one's fixed DMA before decoding this frame. Reading - ;; one channel-upload-info past this record is deliberate. - (b.z uploads-left frame-ready :delay (nop!)) - (l.w dma-address upload (+ (type-size channel-upload-info) (offset-of channel-upload-info fixed))) - (m! scratchpad-address (joint-spad-offset fixed-data)) - (l.w quadword-count upload (+ (type-size channel-upload-info) (offset-of channel-upload-info fixed-qwc))) - (m! dma-control DMA-CHCR-STR) - (s.w dma-address (-> to-spr-channel madr)) - (nop!) - (s.w scratchpad-address (-> to-spr-channel sadr)) - (nop!) - (s.w quadword-count (-> to-spr-channel qwc)) - (sync.l) - (s.w dma-control (-> to-spr-channel chcr)) - (sync.l) - (label frame-ready) - (l.w interpolation upload (offset-of channel-upload-info interp)) - (m! frame-data (&+ (scratchpad-object terrain-context) (joint-spad-offset frame-data))) - (l.w weight upload (offset-of channel-upload-info amount)) - ;; A nonzero interp means flatten-joint-control-to-spr doubled frame-qwc and brought the next - ;; frame across right behind this one, so the pair decoder gets the stride in bytes. - (b.z interpolation single-frame :delay (nop!)) - (l.w second-frame-offset upload (offset-of channel-upload-info frame-qwc)) - (sll second-frame-offset second-frame-offset 3) - (jalr ra decompress-frame-data-pair-to-accumulator :delay (nop!)) - (b.nz uploads-left next-upload :delay (&+! upload (type-size channel-upload-info))) - (b normalize-result :delay (nop!)) - (label single-frame) - (jalr ra decompress-frame-data-to-accumulator :delay (nop!)) - (b.nz uploads-left next-upload :delay (&+! upload (type-size channel-upload-info))) - (label normalize-result) - (m! saved-joint-count joint-count) - (jalr ra normalize-frame-quaternions :delay (nop!)) - (label animation-complete) - (jr ra :delay (nop!))))) - -(defun create-interpolated-joint-animation-frame ((destination (inline-array vector)) (joint-count int) (drawable process-drawable)) +(defun create-interpolated-joint-animation-frame ((destination joint-anim-frame) (joint-count int) (drawable process-drawable)) "Generate drawable's blended joint-animation frame. The GOAL decompressor is normally used; the scratchpad decompressor remains available through the development switch." (cond - (*use-new-decompressor* (new-joint-decompressor (the joint-anim-frame destination) joint-count (-> drawable skel))) + (*use-new-decompressor* + (new-joint-decompressor destination joint-count (-> drawable skel))) (else - (flatten-joint-control-to-spr (-> drawable skel)) - (make-joint-jump-tables) - (calc-animation-from-spr destination joint-count))) - 0) + (crash!) + ;; (flatten-joint-control-to-spr (-> drawable skel)) + ;; (make-joint-jump-tables) + ;; (calc-animation-from-spr destination joint-count) + )) + (none)) diff --git a/goal_src/jak1/engine/collide/collide-func.gc b/goal_src/jak1/engine/collide/collide-func.gc index ec1711108e..bf538f83b1 100644 --- a/goal_src/jak1/engine/collide/collide-func.gc +++ b/goal_src/jak1/engine/collide/collide-func.gc @@ -44,6 +44,8 @@ "Check if a ray intersects a sphere at the origin. Return the fraction along the ray where the intersection occurs, or COLLISION_MISS if there is no collision." + + ;; This function is rewritten in plain GOAL ;; Parameterize the ray with: ;; ray(t) = origin + t * direction with 0 <= t <= 1 @@ -109,6 +111,9 @@ "Compute intersection between a ray and a sphere. Return the fraction along the ray where the intersection occurs, or COLLISION_MISS if there is no collision." + + ;; This function is rewritten in plain GOAL + (#when COLLIDE_FUNC_COUNTERS (+! *ray-sphere-intersect-count* 1)) @@ -122,6 +127,9 @@ The y components of all arguments are ignored. Return the fraction along the ray where the intersection occurs, or COLLISION_MISS if there is no collision." + + ;; This function is rewritten in plain GOAL + (#when COLLIDE_FUNC_COUNTERS (+! *ray-circle-intersect-count* 1)) @@ -146,6 +154,9 @@ If the ray enters through the end cap, returns COLLISION_MISS, even if it later exits the cylinder through a curved wall!" + ;; This function is rewritten in plain GOAL + + (#when COLLIDE_FUNC_COUNTERS (+! *ray-cylinder-intersect-count* 1)) @@ -210,6 +221,8 @@ "Sweep a sphere against the vertices and edges of a triangle, returning the earliest contact fraction or COLLISION_MISS. The triangle face is handled by moving-sphere-triangle-intersect." + + ;; This function is rewritten in plain GOAL ;; These intentionally capture the function's arguments and the best-hit locals below. (defmacro check-vertex (vertex-index) @@ -278,6 +291,8 @@ "Sweep a sphere against a triangle, returning the fraction where the first collision occurs or COLLISION_MISS. This checks the face first, then the rounded vertex and edge boundary." + + ;; This function is rewritten in plain GOAL ;; This intentionally captures edge-a, edge-c, and normal below. (defmacro inside-triangle? (point) diff --git a/goal_src/jak1/engine/common-obs/process-drawable.gc b/goal_src/jak1/engine/common-obs/process-drawable.gc index ed88af325f..34a9e992ca 100644 --- a/goal_src/jak1/engine/common-obs/process-drawable.gc +++ b/goal_src/jak1/engine/common-obs/process-drawable.gc @@ -325,7 +325,7 @@ (let ((frame-node-count (+ joint-count 2))) (+ frame-node-count 1) ((-> this skel generate-frame-function) - (the-as (inline-array vector) (+ 2416 (the-as int (the-as terrain-context (scratchpad-object int))))) + (the-as joint-anim-frame (+ 2416 (the-as int (the-as terrain-context (scratchpad-object int))))) frame-node-count this) (if (-> this skel prebind-function) diff --git a/goal_src/jak1/engine/math/matrix-h.gc b/goal_src/jak1/engine/math/matrix-h.gc index 05b8b7c8a3..135694d3da 100644 --- a/goal_src/jak1/engine/math/matrix-h.gc +++ b/goal_src/jak1/engine/math/matrix-h.gc @@ -5,6 +5,15 @@ ;; DECOMP BEGINS +;; GOAL uses the convention or row-major matrices, but row-vector points + +;; [ Xx Xy Xz 0 ] local X basis row +;; [ Yx Yy Yz 0 ] local Y basis row +;; [ Zx Zy Zz 0 ] local Z basis row +;; [ Tx Ty Tz 1 ] translation row + +;; with pt' = pt * M + ;; A row-major 4x4 matrix. Some operations require an affine transform, and the ;; fastest inverse operations additionally require rotation without scale or shear. (deftype matrix (structure)