sm64

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

ttc_pendulum.inc.c (2930B)


      1 
      2 /**
      3  * Behavior for bhvTTCPendulum. This is not the pendulum inside the clock in the
      4  * castle, but rather the one in TTC itself.
      5  */
      6 
      7 /**
      8  * Initial angle acceleration.
      9  */
     10 static f32 sTTCPendulumInitialAccels[] = {
     11     /* TTC_SPEED_SLOW    */ 13.0f,
     12     /* TTC_SPEED_FAST    */ 22.0f,
     13     /* TTC_SPEED_RANDOM  */ 13.0f,
     14     /* TTC_SPEED_STOPPED */ 0.0f,
     15 };
     16 
     17 /**
     18  * Init function for bhvTTCPendulum.
     19  */
     20 void bhv_ttc_pendulum_init(void) {
     21     if (gTTCSpeedSetting != TTC_SPEED_STOPPED) {
     22         o->oTTCPendulumAngleAccel = sTTCPendulumInitialAccels[gTTCSpeedSetting];
     23         o->oTTCPendulumAngle = 6500.0f;
     24     } else {
     25         o->oTTCPendulumAngle = 6371.5557f;
     26     }
     27 }
     28 
     29 /**
     30  * Update function for bhvTTCPendulum.
     31  */
     32 void bhv_ttc_pendulum_update(void) {
     33     if (gTTCSpeedSetting != TTC_SPEED_STOPPED) {
     34         UNUSED f32 startVel = o->oTTCPendulumAngleVel;
     35 
     36         // Play sound
     37         if (o->oTTCPendulumSoundTimer != 0) {
     38             if (--o->oTTCPendulumSoundTimer == 0) {
     39                 cur_obj_play_sound_2(SOUND_GENERAL_PENDULUM_SWING);
     40             }
     41         }
     42 
     43         // Stay still for a while
     44         if (o->oTTCPendulumDelay != 0) {
     45             o->oTTCPendulumDelay--;
     46         } else {
     47             // Accelerate in the direction that moves angle to zero
     48             if (o->oTTCPendulumAngle * o->oTTCPendulumAccelDir > 0.0f) {
     49                 o->oTTCPendulumAccelDir = -o->oTTCPendulumAccelDir;
     50             }
     51             o->oTTCPendulumAngleVel += o->oTTCPendulumAngleAccel * o->oTTCPendulumAccelDir;
     52 
     53             // Ignoring floating point imprecision, angle vel should always be
     54             // a multiple of angle accel, and so it will eventually reach zero
     55             //! If the pendulum is moving fast enough, the vel could fail to
     56             //  be a multiple of angle accel, and so the pendulum would continue
     57             //  oscillating forever
     58             if (o->oTTCPendulumAngleVel == 0.0f) {
     59                 if (gTTCSpeedSetting == TTC_SPEED_RANDOM) {
     60                     // Select a new acceleration
     61                     //! By manipulating this, we can cause the pendulum to reach
     62                     //  extreme angles and speeds
     63                     if (random_u16() % 3 != 0) {
     64                         o->oTTCPendulumAngleAccel = 13.0f;
     65                     } else {
     66                         o->oTTCPendulumAngleAccel = 42.0f;
     67                     }
     68 
     69                     // Pick a random delay
     70                     if (random_u16() % 2 == 0) {
     71                         o->oTTCPendulumDelay = random_linear_offset(5, 30);
     72                     }
     73                 }
     74 
     75                 // Play the sound 15 frames after beginning to move
     76                 o->oTTCPendulumSoundTimer = o->oTTCPendulumDelay + 15;
     77             }
     78 
     79             o->oTTCPendulumAngle += o->oTTCPendulumAngleVel;
     80         }
     81     } else {
     82     }
     83 
     84     o->oFaceAngleRoll = (s32) o->oTTCPendulumAngle;
     85     // Note: no platform displacement
     86 }