sm64

A Super Mario 64 decompilation
Log | Files | Refs | README | LICENSE

skin.c (16939B)


      1 #include <PR/ultratypes.h>
      2 
      3 #ifdef VERSION_EU
      4 #include "prevent_bss_reordering.h"
      5 #endif
      6 
      7 #include "debug_utils.h"
      8 #include "gd_main.h"
      9 #include "gd_math.h"
     10 #include "gd_types.h"
     11 #include "joints.h"
     12 #include "macros.h"
     13 #include "objects.h"
     14 #include "particles.h"
     15 #include "renderer.h"
     16 #include "skin.h"
     17 #include "skin_movement.h"
     18 
     19 // bss
     20 struct ObjNet *gGdSkinNet; // @ 801BAAF0
     21 
     22 static s32 D_801BAAF4;
     23 static s32 sNetCount; // @ 801BAAF8
     24 
     25 /* 2406E0 -> 240894 */
     26 void compute_net_bounding_box(struct ObjNet *net) {
     27     reset_bounding_box();
     28     if (net->unk1D0 != NULL) {
     29         apply_to_obj_types_in_group(OBJ_TYPE_ALL, (applyproc_t) add_obj_pos_to_bounding_box, net->unk1D0);
     30     }
     31     if (net->unk1C8 != NULL) {
     32         apply_to_obj_types_in_group(OBJ_TYPE_ALL, (applyproc_t) add_obj_pos_to_bounding_box, net->unk1C8);
     33     }
     34     gSomeBoundingBox.minX *= net->scale.x;
     35     gSomeBoundingBox.maxX *= net->scale.x;
     36     gSomeBoundingBox.minY *= net->scale.y;
     37     gSomeBoundingBox.maxY *= net->scale.y;
     38     gSomeBoundingBox.minZ *= net->scale.z;
     39     gSomeBoundingBox.maxZ *= net->scale.z;
     40 
     41     net->boundingBox.minX = gSomeBoundingBox.minX;
     42     net->boundingBox.minY = gSomeBoundingBox.minY;
     43     net->boundingBox.minZ = gSomeBoundingBox.minZ;
     44     net->boundingBox.maxX = gSomeBoundingBox.maxX;
     45     net->boundingBox.maxY = gSomeBoundingBox.maxY;
     46     net->boundingBox.maxZ = gSomeBoundingBox.maxZ;
     47 }
     48 
     49 /* 240894 -> 240A64; orig name: func_801920C4 */
     50 void reset_net(struct ObjNet *net) {
     51     struct ObjGroup *grp;
     52 
     53     printf("reset_net %d\n", net->id);
     54 
     55     net->worldPos.x = net->initPos.x;
     56     net->worldPos.y = net->initPos.y;
     57     net->worldPos.z = net->initPos.z;
     58     net->velocity.x = net->velocity.y = net->velocity.z = 0.0f;
     59     net->torque.x = net->torque.y = net->torque.z = 0.0f;
     60 
     61     compute_net_bounding_box(net);
     62     gd_print_vec("net scale: ", &net->scale);
     63     gd_print_bounding_box("net box: ", &net->boundingBox);
     64 
     65     gGdSkinNet = net;
     66     D_801BAAF4 = 0;
     67     gd_set_identity_mat4(&net->mat168);
     68     gd_set_identity_mat4(&net->matE8);
     69     gd_rot_mat_about_vec(&net->matE8, &net->unk68); // set rot mtx to initial rotation?
     70     gd_add_vec3f_to_mat4f_offset(&net->matE8, &net->worldPos); // set to initial position?
     71     gd_copy_mat4f(&net->matE8, &net->mat128);
     72 
     73     if ((grp = net->unk1C8) != NULL) {
     74         apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) reset_joint, grp);
     75         apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_80191220, grp);
     76         apply_to_obj_types_in_group(OBJ_TYPE_BONES, (applyproc_t) func_8018FB58, grp);
     77         apply_to_obj_types_in_group(OBJ_TYPE_BONES, (applyproc_t) func_8018FA68, grp);
     78     }
     79 }
     80 
     81 /* 240A64 -> 240ACC */
     82 void func_80192294(struct ObjNet *net) {
     83     UNUSED s32 sp1C = 0;
     84 
     85     if (net->attachedToObj == NULL) {
     86         restart_timer("childpos");
     87         sp1C = transform_child_objects_recursive(&net->header, NULL);
     88         split_timer("childpos");
     89     }
     90 }
     91 
     92 /* 240ACC -> 240B84 */
     93 void func_801922FC(struct ObjNet *net) {
     94     struct ObjGroup *group; // 24
     95     UNUSED u8 filler[8];
     96 
     97     gGdSkinNet = net;
     98     // TODO: netype constants?
     99     if (net->netType == 4) {
    100         if (net->shapePtr != NULL) {
    101             D_801B9E38 = &net->mat128;
    102             scale_verts(net->shapePtr->vtxGroup);
    103         }
    104         if ((group = net->unk1C8) != NULL) {
    105             apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) reset_joint_weights, group);
    106         }
    107     }
    108 }
    109 
    110 /* 240B84 -> 240CF8 */
    111 struct ObjNet *make_net(UNUSED s32 a0, struct ObjShape *shapedata, struct ObjGroup *a2,
    112                         struct ObjGroup *a3, struct ObjGroup *a4) {
    113     struct ObjNet *net;
    114 
    115     net = (struct ObjNet *) make_object(OBJ_TYPE_NETS);
    116     gd_set_identity_mat4(&net->mat128);
    117     net->initPos.x = net->initPos.y = net->initPos.z = 0.0f;
    118     net->id = ++sNetCount;
    119     net->scale.x = net->scale.y = net->scale.z = 1.0f;
    120     net->shapePtr = shapedata;
    121     net->unk1C8 = a2;
    122     net->unk1CC = a3;
    123     net->unk1D0 = a4;
    124     net->netType = 0;
    125     net->ctrlType = 0;
    126     net->unk21C = NULL;
    127     net->unk3C = 1;
    128     net->colourNum = 0;
    129     net->skinGrp = NULL;
    130     reset_net(net);
    131 
    132     return net;
    133 }
    134 
    135 /* 240CF8 -> 240E74 */
    136 void func_80192528(struct ObjNet *net) {
    137     net->unusedForce.x = net->unusedForce.y = net->unusedForce.z = 0.0f;
    138     net->collDisp.x = net->collDisp.y = net->collDisp.z = 0.0f;
    139     net->collTorque.x = net->collTorque.y = net->collTorque.z = 0.0f;
    140     net->unusedCollDispOff.x = net->unusedCollDispOff.y = net->unusedCollDispOff.z = 0.0f;
    141     net->unusedCollMaxD = 0.0f;
    142 
    143     gGdCounter.ctr0 = 0;
    144     gGdCounter.ctr1 = 0;
    145     D_801B9E18.x = 0.0f;
    146     D_801B9E18.y = 0.0f;
    147     D_801B9E18.z = 0.0f;
    148     D_801B9E28.x = 0.0f;
    149     D_801B9E28.y = 0.0f;
    150     D_801B9E28.z = 0.0f;
    151     D_801B9E34 = 0.0f;
    152 
    153     if (net->flags & 0x1) {
    154         net->velocity.y += -4.0; //? 4.0f
    155     }
    156 
    157     net->worldPos.x += net->velocity.x / 1.0f;
    158     net->worldPos.y += net->velocity.y / 1.0f;
    159     net->worldPos.z += net->velocity.z / 1.0f;
    160 }
    161 
    162 /* 240E74 -> 2412A0 */
    163 void collision_something_801926A4(struct ObjNet *net) {
    164     if (gGdCounter.ctr1 != 0) {
    165         if (D_801B9E34 != 0.0f) {
    166             D_801B9E28.x /= D_801B9E34;
    167             D_801B9E28.y /= D_801B9E34;
    168             D_801B9E28.z /= D_801B9E34;
    169         }
    170 
    171         D_801B9E28.x *= 1.0 / gGdCounter.ctr1; // !1.0f
    172         D_801B9E28.y *= 1.0 / gGdCounter.ctr1; // !1.0f
    173         D_801B9E28.z *= 1.0 / gGdCounter.ctr1; // !1.0f
    174         D_801B9E18.x *= 1.0 / gGdCounter.ctr1; // !1.0f
    175         D_801B9E18.y *= 1.0 / gGdCounter.ctr1; // !1.0f
    176         D_801B9E18.z *= 1.0 / gGdCounter.ctr1; // !1.0f
    177 
    178         func_8017E584(gGdSkinNet, &D_801B9E28, &D_801B9E18);
    179         func_8017E838(gGdSkinNet, &D_801B9E28, &D_801B9E18);
    180     }
    181 
    182     net->torque.x += net->collTorque.x;
    183     net->torque.y += net->collTorque.y;
    184     net->torque.z += net->collTorque.z;
    185     net->collDisp.x *= 1.0; // 1.0f;
    186     net->collDisp.y *= 1.0; // 1.0f;
    187     net->collDisp.z *= 1.0; // 1.0f;
    188     net->velocity.x += net->collDisp.x;
    189     net->velocity.y += net->collDisp.y;
    190     net->velocity.z += net->collDisp.z;
    191     net->worldPos.x += net->collDisp.x;
    192     net->worldPos.y += net->collDisp.y;
    193     net->worldPos.z += net->collDisp.z;
    194     func_8017E9EC(net);
    195 
    196     net->torque.x *= 0.98; //? 0.98f
    197     net->torque.z *= 0.98; //? 0.98f
    198     net->torque.y *= 0.9;  //? 0.9f
    199 }
    200 
    201 /* 2412A0 -> 24142C; not called */
    202 void func_80192AD0(struct ObjNet *net) {
    203     UNUSED u8 filler1[4];
    204     struct ObjGroup *sp60;
    205     UNUSED u8 filler2[68];
    206     struct ObjNet *sp18;
    207 
    208     if ((sp60 = net->unk1C8) == NULL) {
    209         return;
    210     }
    211 
    212     sp18 = net->unk1F0;
    213     net->worldPos.x = net->unk1F4.x;
    214     net->worldPos.y = net->unk1F4.y;
    215     net->worldPos.z = net->unk1F4.z;
    216     gd_rotate_and_translate_vec3f(&net->worldPos, &sp18->mat128);
    217 
    218     net->worldPos.x += net->unk1F0->worldPos.x;
    219     net->worldPos.y += net->unk1F0->worldPos.y;
    220     net->worldPos.z += net->unk1F0->worldPos.z;
    221     net->unk200.x = 0.0f;
    222     net->unk200.y = 10.0f;
    223     net->unk200.z = -4.0f;
    224     gd_rotate_and_translate_vec3f(&net->unk200, &sp18->mat128);
    225 
    226     apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_80191824, sp60);
    227     func_80191E88(sp60);
    228     apply_to_obj_types_in_group(OBJ_TYPE_BONES, (applyproc_t) func_8018F328, net->unk20C);
    229 }
    230 
    231 /* 24142C -> 24149C; orig name: func_80192C5C */
    232 void move_bonesnet(struct ObjNet *net) {
    233     struct ObjGroup *sp24;
    234     UNUSED u8 filler[12];
    235 
    236     imin("move_bonesnet");
    237     gd_set_identity_mat4(&D_801B9DC8);
    238     if ((sp24 = net->unk1C8) != NULL) {
    239         apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_801913C0, sp24);
    240     }
    241     imout();
    242 }
    243 
    244 /* 24149C -> 241768 */
    245 void func_80192CCC(struct ObjNet *net) {
    246     Mat4f sp38;
    247     UNUSED struct GdControl *ctrl; // 34
    248     struct ObjGroup *group;        // 30
    249     struct GdVec3f sp24;
    250 
    251     ctrl = &gGdCtrl;
    252     if (gGdCtrl.unk2C != NULL) {
    253         menu_cb_reset_positions();
    254     }
    255     gd_set_identity_mat4(&D_801B9DC8);
    256 
    257     if (gGdCtrl.unk30 != NULL) {
    258         sp24.x = net->mat128[0][0];
    259         sp24.y = net->mat128[0][1];
    260         sp24.z = net->mat128[0][2];
    261         gd_create_rot_mat_angular(&sp38, &sp24, 4.0f);
    262         gd_mult_mat4f(&sp38, &D_801B9DC8, &D_801B9DC8);
    263         net->torque.x = net->torque.y = net->torque.z = 0.0f;
    264     }
    265 
    266     if (gGdCtrl.unk28 != NULL) {
    267         sp24.x = net->mat128[0][0];
    268         sp24.y = net->mat128[0][1];
    269         sp24.z = net->mat128[0][2];
    270         gd_create_rot_mat_angular(&sp38, &sp24, -4.0f);
    271         gd_mult_mat4f(&sp38, &D_801B9DC8, &D_801B9DC8);
    272         net->torque.x = net->torque.y = net->torque.z = 0.0f;
    273     }
    274 
    275     if (gGdCtrl.newStartPress) {
    276         return;
    277     } // start was pressed
    278 
    279     switch (net->ctrlType) {
    280         case 2:
    281             break;
    282     }
    283 
    284     func_80192528(net);
    285     if ((group = net->unk1C8) != NULL) {
    286         apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_80191220, group);
    287         apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_801913F0, group);
    288         apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) stub_joints_2, group);
    289         apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_801911A8, group);
    290     }
    291 
    292     collision_something_801926A4(net);
    293     gd_mult_mat4f(&net->mat128, &D_801B9DC8, &net->mat128);
    294     if (group != NULL) {
    295         apply_to_obj_types_in_group(OBJ_TYPE_JOINTS, (applyproc_t) func_801913C0, group);
    296         apply_to_obj_types_in_group(OBJ_TYPE_BONES, (applyproc_t) func_8018FA68, group);
    297     }
    298 }
    299 
    300 /* 241768 -> 241AB4; orig name: func_80192F98 */
    301 void convert_gd_verts_to_Vn(struct ObjGroup *grp) {
    302     UNUSED u8 filler1[20];
    303     Vtx *vn;       // 28
    304     u8 nx, ny, nz; // 24, 25, 26
    305     UNUSED u8 filler2[4];
    306     register struct VtxLink *vtxlink; // a1
    307 #ifndef GBI_FLOATS
    308     register s16 *vnPos;              // a2
    309 #endif
    310     register s16 x;                   // a3
    311     register s16 y;                   // t0
    312     register s16 z;                   // t1
    313     register struct ObjVertex *vtx;   // t2
    314     register struct ListNode *link;      // t3
    315     struct GdObj *obj;                // sp4
    316 
    317     for (link = grp->firstMember; link != NULL; link = link->next) {
    318         obj = link->obj;
    319         vtx = (struct ObjVertex *) obj;
    320         x = (s16) vtx->pos.x;
    321         y = (s16) vtx->pos.y;
    322         z = (s16) vtx->pos.z;
    323 
    324         nx = (u8)(vtx->normal.x * 255.0f);
    325         ny = (u8)(vtx->normal.y * 255.0f);
    326         nz = (u8)(vtx->normal.z * 255.0f);
    327 
    328         for (vtxlink = vtx->gbiVerts; vtxlink != NULL; vtxlink = vtxlink->prev) {
    329 #ifndef GBI_FLOATS
    330             vnPos = vtxlink->data->n.ob;
    331             vn = vtxlink->data;
    332             *vnPos++ = x;
    333             *vnPos++ = y;
    334             *vnPos++ = z;
    335 #else
    336             vn = vtxlink->data;
    337             vn->n.ob[0] = x;
    338             vn->n.ob[1] = y;
    339             vn->n.ob[2] = z;
    340 #endif
    341             vn->n.n[0] = nx;
    342             vn->n.n[1] = ny;
    343             vn->n.n[2] = nz;
    344         }
    345     }
    346 }
    347 
    348 /* 241AB4 -> 241BCC; orig name: func_801932E4 */
    349 void convert_gd_verts_to_Vtx(struct ObjGroup *grp) {
    350     UNUSED u8 filler[24];
    351     register struct VtxLink *vtxlink; // a1
    352 #ifndef GBI_FLOATS
    353     register s16 *vtxcoords;          // a2
    354 #endif
    355     register s16 x;                   // a3
    356     register s16 y;                   // t0
    357     register s16 z;                   // t1
    358     register struct ObjVertex *vtx;   // t2
    359     register struct ListNode *link;      // t3
    360     struct GdObj *obj;                // sp4
    361 
    362     for (link = grp->firstMember; link != NULL; link = link->next) {
    363         obj = link->obj;
    364         vtx = (struct ObjVertex *) obj;
    365         x = (s16) vtx->pos.x;
    366         y = (s16) vtx->pos.y;
    367         z = (s16) vtx->pos.z;
    368 
    369         for (vtxlink = vtx->gbiVerts; vtxlink != NULL; vtxlink = vtxlink->prev) {
    370 #ifndef GBI_FLOATS
    371             vtxcoords = vtxlink->data->v.ob;
    372             vtxcoords[0] = x;
    373             vtxcoords[1] = y;
    374             vtxcoords[2] = z;
    375 #else
    376             vtxlink->data->v.ob[0] = x;
    377             vtxlink->data->v.ob[1] = y;
    378             vtxlink->data->v.ob[2] = z;
    379 #endif
    380         }
    381     }
    382 }
    383 
    384 /* 241BCC -> 241CA0; orig name: Proc801933FC */
    385 void convert_net_verts(struct ObjNet *net) {
    386     if (net->shapePtr != NULL) {
    387         if (net->shapePtr->unk30) {
    388             convert_gd_verts_to_Vn(net->shapePtr->vtxGroup);
    389         }
    390     }
    391 
    392     switch (net->netType) {
    393         case 2:
    394             if (net->shapePtr != NULL) {
    395                 convert_gd_verts_to_Vtx(net->shapePtr->scaledVtxGroup);
    396             }
    397             break;
    398     }
    399 }
    400 
    401 /* 241CA0 -> 241D6C */
    402 static void move_joints_in_net(struct ObjNet *net) {
    403     struct ObjGroup *grp;        // 2c
    404     register struct ListNode *link; // s0
    405     struct GdObj *obj;           // 24
    406 
    407     if ((grp = net->unk1C8) != NULL) {
    408         for (link = grp->firstMember; link != NULL; link = link->next) {
    409             obj = link->obj;
    410             switch (obj->type) {
    411                 case OBJ_TYPE_JOINTS:
    412                     if (((struct ObjJoint *) obj)->updateFunc != NULL) {
    413                         (*((struct ObjJoint *) obj)->updateFunc)((struct ObjJoint *) obj);
    414                     }
    415                     break;
    416                 default:;
    417             }
    418         }
    419     }
    420 }
    421 
    422 /* 241D6C -> 241E94; orig name: func_8019359C */
    423 void move_net(struct ObjNet *net) {
    424     gGdSkinNet = net;
    425 
    426     switch (net->netType) {
    427         case 1:
    428             break;
    429         case 7:
    430             func_80192CCC(net);
    431             break;
    432         case 4:
    433             restart_timer("move_bones");
    434             move_bonesnet(net);
    435             split_timer("move_bones");
    436             break;
    437         case 2:
    438             restart_timer("move_skin");
    439             move_skin(net);
    440             split_timer("move_skin");
    441             break;
    442         case 3:
    443             move_joints_in_net(net);
    444             break;
    445         case 5:
    446             func_801823A0(net);
    447             break;
    448         case 6:
    449             break;
    450         default:
    451             fatal_printf("move_net(%d(%d)): Undefined net type", net->id, net->netType);
    452     }
    453 }
    454 
    455 /* 241E94 -> 241F0C; orig name: func_801936C4 */
    456 void move_nets(struct ObjGroup *group) {
    457     imin("move_nets");
    458     restart_timer("move_nets");
    459     apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) func_80192294, group);
    460     apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) move_net, group);
    461     split_timer("move_nets");
    462     imout();
    463 }
    464 
    465 /* 241F0C -> 242018 */
    466 void func_8019373C(struct ObjNet *net) {
    467     register struct ListNode *link;
    468     struct ObjVertex *vtx;
    469 
    470     switch (net->netType) {
    471         case 2:
    472             if (net->shapePtr != NULL) {
    473                 net->shapePtr->scaledVtxGroup = make_group(0);
    474                 for (link = net->shapePtr->vtxGroup->firstMember; link != NULL; link = link->next) {
    475                     vtx = (struct ObjVertex *) link->obj;
    476                     if (vtx->scaleFactor != 1.0) {
    477                         addto_group(net->shapePtr->scaledVtxGroup, &vtx->header);
    478                     }
    479                 }
    480             }
    481             break;
    482     }
    483 }
    484 
    485 /* 242018 -> 24208C */
    486 void func_80193848(struct ObjGroup *group) {
    487     apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) reset_net, group);
    488     apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) func_80192294, group);
    489     apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) func_801922FC, group);
    490     apply_to_obj_types_in_group(OBJ_TYPE_NETS, (applyproc_t) func_8019373C, group);
    491 }
    492 
    493 /* 24208C -> 2422E0; not called; orig name: func_801938BC */
    494 void gd_print_net(struct ObjNet *net) {
    495     gd_printf("Flags:%x\n", net->flags);
    496     gd_print_vec("World:", &net->worldPos);
    497     gd_print_vec("Force:", &net->unusedForce);
    498     gd_print_vec("Vel:", &net->velocity);
    499     gd_print_vec("Rot:", &net->rotation);
    500     gd_print_vec("CollDisp:", &net->collDisp);
    501     gd_print_vec("CollTorque:", &net->collTorque);
    502     gd_print_vec("CollTorqueL:", &net->unusedCollTorqueL);
    503     gd_print_vec("CollTorqueD:", &net->unusedCollTorqueD);
    504     gd_print_vec("Torque:", &net->torque);
    505     gd_print_vec("CofG:", &net->centerOfGravity);
    506     gd_print_bounding_box("BoundBox:", &net->boundingBox);
    507     gd_print_vec("CollDispOff:", &net->unusedCollDispOff);
    508     gd_printf("CollMaxD: %f\n", net->unusedCollMaxD);
    509     gd_printf("MaxRadius: %f\n", net->maxRadius);
    510     gd_print_mtx("Matrix:", &net->mat128);
    511     if (net->shapePtr != NULL) {
    512         gd_printf("ShapePtr: %x (%s)\n", (u32) (uintptr_t) net->shapePtr, net->shapePtr->name);
    513     } else {
    514         gd_printf("ShapePtr: NULL\n");
    515     }
    516     gd_print_vec("Scale:", &net->scale);
    517     gd_printf("Mass: %f\n", net->unusedMass);
    518     gd_printf("NumModes: %d\n", net->numModes);
    519     gd_printf("NodeGroup: %x\n", (u32) (uintptr_t) net->unk1C8);
    520     gd_printf("PlaneGroup: %x\n", (u32) (uintptr_t) net->unk1CC);
    521     gd_printf("VertexGroup: %x\n", (u32) (uintptr_t) net->unk1D0);
    522 }
    523 
    524 /* 2422E0 -> 2422F8; orig name: func_80193B10 */
    525 void reset_net_count(void) {
    526     sNetCount = 0;
    527 }