sm64

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

tilting_inverted_pyramid.inc.c (3997B)


      1 
      2 /**
      3  * This is the behavior file for the tilting inverted pyramids in BitFS/LLL.
      4  * The object essentially just tilts and moves Mario with it.
      5  */
      6 
      7 /**
      8  * Creates a transform matrix on a variable passed in from given normals
      9  * and the object's position.
     10  */
     11 void create_transform_from_normals(Mat4 transform, f32 xNorm, f32 yNorm, f32 zNorm) {
     12     Vec3f normal;
     13     Vec3f pos;
     14 
     15     pos[0] = o->oPosX;
     16     pos[1] = o->oPosY;
     17     pos[2] = o->oPosZ;
     18 
     19     normal[0] = xNorm;
     20     normal[1] = yNorm;
     21     normal[2] = zNorm;
     22 
     23     mtxf_align_terrain_normal(transform, normal, pos, 0);
     24 }
     25 
     26 /**
     27  * Initialize the object's transform matrix with Y being up.
     28  */
     29 void bhv_platform_normals_init(void) {
     30     Mat4 *transform = &o->transform;
     31 
     32     o->oTiltingPyramidNormalX = 0.0f;
     33     o->oTiltingPyramidNormalY = 1.0f;
     34     o->oTiltingPyramidNormalZ = 0.0f;
     35 
     36     create_transform_from_normals(*transform, 0.0f, 1.0f, 0.0f);
     37 }
     38 
     39 /**
     40  * Returns a value that is src incremented/decremented by inc towards goal
     41  * until goal is reached. Does not overshoot.
     42  */
     43 f32 approach_by_increment(f32 goal, f32 src, f32 inc) {
     44     f32 newVal;
     45 
     46     if (src <= goal) {
     47         if (goal - src < inc) {
     48             newVal = goal;
     49         } else {
     50             newVal = src + inc;
     51         }
     52     } else if (goal - src > -inc) {
     53         newVal = goal;
     54     } else {
     55         newVal = src - inc;
     56     }
     57 
     58     return newVal;
     59 }
     60 
     61 /**
     62  * Main behavior for the tilting pyramids in LLL/BitFS. These platforms calculate rough normals from Mario's position,
     63  * then gradually tilt back moving Mario with them.
     64  */
     65 void bhv_tilting_inverted_pyramid_loop(void) {
     66     f32 dx;
     67     f32 dy;
     68     f32 dz;
     69     f32 d;
     70 
     71     Vec3f dist;
     72     Vec3f posBeforeRotation;
     73     Vec3f posAfterRotation;
     74 
     75     // Mario's position
     76     f32 mx;
     77     f32 my;
     78     f32 mz;
     79 
     80     s32 marioOnPlatform = FALSE;
     81     UNUSED u8 filler1[4];
     82     Mat4 *transform = &o->transform;
     83     UNUSED u8 filler2[28];
     84 
     85     if (gMarioObject->platform == o) {
     86         get_mario_pos(&mx, &my, &mz);
     87 
     88         dist[0] = gMarioObject->oPosX - o->oPosX;
     89         dist[1] = gMarioObject->oPosY - o->oPosY;
     90         dist[2] = gMarioObject->oPosZ - o->oPosZ;
     91         linear_mtxf_mul_vec3f(*transform, posBeforeRotation, dist);
     92 
     93         dx = gMarioObject->oPosX - o->oPosX;
     94         dy = 500.0f;
     95         dz = gMarioObject->oPosZ - o->oPosZ;
     96         d = sqrtf(dx * dx + dy * dy + dz * dz);
     97 
     98         //! Always true since dy = 500, making d >= 500.
     99         if (d != 0.0f) {
    100             // Normalizing
    101             d = 1.0 / d;
    102             dx *= d;
    103             dy *= d;
    104             dz *= d;
    105         } else {
    106             dx = 0.0f;
    107             dy = 1.0f;
    108             dz = 0.0f;
    109         }
    110 
    111         if (o->oTiltingPyramidMarioOnPlatform == TRUE) {
    112             marioOnPlatform++;
    113         }
    114 
    115         o->oTiltingPyramidMarioOnPlatform = TRUE;
    116     } else {
    117         dx = 0.0f;
    118         dy = 1.0f;
    119         dz = 0.0f;
    120         o->oTiltingPyramidMarioOnPlatform = FALSE;
    121     }
    122 
    123     // Approach the normals by 0.01f towards the new goal, then create a transform matrix and orient the object.
    124     // Outside of the other conditionals since it needs to tilt regardless of whether Mario is on.
    125     o->oTiltingPyramidNormalX = approach_by_increment(dx, o->oTiltingPyramidNormalX, 0.01f);
    126     o->oTiltingPyramidNormalY = approach_by_increment(dy, o->oTiltingPyramidNormalY, 0.01f);
    127     o->oTiltingPyramidNormalZ = approach_by_increment(dz, o->oTiltingPyramidNormalZ, 0.01f);
    128     create_transform_from_normals(*transform, o->oTiltingPyramidNormalX, o->oTiltingPyramidNormalY, o->oTiltingPyramidNormalZ);
    129 
    130     // If Mario is on the platform, adjust his position for the platform tilt.
    131     if (marioOnPlatform) {
    132         linear_mtxf_mul_vec3f(*transform, posAfterRotation, dist);
    133         mx += posAfterRotation[0] - posBeforeRotation[0];
    134         my += posAfterRotation[1] - posBeforeRotation[1];
    135         mz += posAfterRotation[2] - posBeforeRotation[2];
    136         set_mario_pos(mx, my, mz);
    137     }
    138 
    139     o->header.gfx.throwMatrix = transform;
    140 }