sm64

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

mario_actions_moving.c (63401B)


      1 #include <PR/ultratypes.h>
      2 
      3 #include "sm64.h"
      4 #include "mario.h"
      5 #include "audio/external.h"
      6 #include "engine/math_util.h"
      7 #include "engine/surface_collision.h"
      8 #include "mario_step.h"
      9 #include "area.h"
     10 #include "interaction.h"
     11 #include "mario_actions_object.h"
     12 #include "memory.h"
     13 #include "behavior_data.h"
     14 #include "rumble_init.h"
     15 
     16 struct LandingAction {
     17     s16 numFrames;
     18     s16 unk02;
     19     u32 verySteepAction;
     20     u32 endAction;
     21     u32 aPressedAction;
     22     u32 offFloorAction;
     23     u32 slideAction;
     24 };
     25 
     26 struct LandingAction sJumpLandAction = {
     27     4, 5, ACT_FREEFALL, ACT_JUMP_LAND_STOP, ACT_DOUBLE_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
     28 };
     29 
     30 struct LandingAction sFreefallLandAction = {
     31     4, 5, ACT_FREEFALL, ACT_FREEFALL_LAND_STOP, ACT_DOUBLE_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
     32 };
     33 
     34 struct LandingAction sSideFlipLandAction = {
     35     4, 5, ACT_FREEFALL, ACT_SIDE_FLIP_LAND_STOP, ACT_DOUBLE_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
     36 };
     37 
     38 struct LandingAction sHoldJumpLandAction = {
     39     4, 5, ACT_HOLD_FREEFALL, ACT_HOLD_JUMP_LAND_STOP, ACT_HOLD_JUMP, ACT_HOLD_FREEFALL, ACT_HOLD_BEGIN_SLIDING,
     40 };
     41 
     42 struct LandingAction sHoldFreefallLandAction = {
     43     4, 5, ACT_HOLD_FREEFALL, ACT_HOLD_FREEFALL_LAND_STOP, ACT_HOLD_JUMP, ACT_HOLD_FREEFALL, ACT_HOLD_BEGIN_SLIDING,
     44 };
     45 
     46 struct LandingAction sLongJumpLandAction = {
     47     6, 5, ACT_FREEFALL, ACT_LONG_JUMP_LAND_STOP, ACT_LONG_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
     48 };
     49 
     50 struct LandingAction sDoubleJumpLandAction = {
     51     4, 5, ACT_FREEFALL, ACT_DOUBLE_JUMP_LAND_STOP, ACT_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
     52 };
     53 
     54 struct LandingAction sTripleJumpLandAction = {
     55     4, 0, ACT_FREEFALL, ACT_TRIPLE_JUMP_LAND_STOP, ACT_UNINITIALIZED, ACT_FREEFALL, ACT_BEGIN_SLIDING,
     56 };
     57 
     58 struct LandingAction sBackflipLandAction = {
     59     4, 0, ACT_FREEFALL, ACT_BACKFLIP_LAND_STOP, ACT_BACKFLIP, ACT_FREEFALL, ACT_BEGIN_SLIDING,
     60 };
     61 
     62 Mat4 sFloorAlignMatrix[2];
     63 
     64 s16 tilt_body_running(struct MarioState *m) {
     65     s16 pitch = find_floor_slope(m, 0);
     66     pitch = pitch * m->forwardVel / 40.0f;
     67     return -pitch;
     68 }
     69 
     70 void play_step_sound(struct MarioState *m, s16 frame1, s16 frame2) {
     71     if (is_anim_past_frame(m, frame1) || is_anim_past_frame(m, frame2)) {
     72         if (m->flags & MARIO_METAL_CAP) {
     73             if (m->marioObj->header.gfx.animInfo.animID == MARIO_ANIM_TIPTOE) {
     74                 play_sound_and_spawn_particles(m, SOUND_ACTION_METAL_STEP_TIPTOE, 0);
     75             } else {
     76                 play_sound_and_spawn_particles(m, SOUND_ACTION_METAL_STEP, 0);
     77             }
     78         } else if (m->quicksandDepth > 50.0f) {
     79             play_sound(SOUND_ACTION_QUICKSAND_STEP, m->marioObj->header.gfx.cameraToObject);
     80         } else if (m->marioObj->header.gfx.animInfo.animID == MARIO_ANIM_TIPTOE) {
     81             play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STEP_TIPTOE, 0);
     82         } else {
     83             play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_STEP, 0);
     84         }
     85     }
     86 }
     87 
     88 void align_with_floor(struct MarioState *m) {
     89     m->pos[1] = m->floorHeight;
     90     mtxf_align_terrain_triangle(sFloorAlignMatrix[m->unk00], m->pos, m->faceAngle[1], 40.0f);
     91     m->marioObj->header.gfx.throwMatrix = &sFloorAlignMatrix[m->unk00];
     92 }
     93 
     94 s32 begin_walking_action(struct MarioState *m, f32 forwardVel, u32 action, u32 actionArg) {
     95     m->faceAngle[1] = m->intendedYaw;
     96     mario_set_forward_vel(m, forwardVel);
     97     return set_mario_action(m, action, actionArg);
     98 }
     99 
    100 void check_ledge_climb_down(struct MarioState *m) {
    101     struct WallCollisionData wallCols;
    102     struct Surface *floor;
    103     f32 floorHeight;
    104     struct Surface *wall;
    105     s16 wallAngle;
    106     s16 wallDYaw;
    107 
    108     if (m->forwardVel < 10.0f) {
    109         wallCols.x = m->pos[0];
    110         wallCols.y = m->pos[1];
    111         wallCols.z = m->pos[2];
    112         wallCols.radius = 10.0f;
    113         wallCols.offsetY = -10.0f;
    114 
    115         if (find_wall_collisions(&wallCols) != 0) {
    116             floorHeight = find_floor(wallCols.x, wallCols.y, wallCols.z, &floor);
    117             if (floor != NULL && (wallCols.y - floorHeight > 160.0f)) {
    118                 wall = wallCols.walls[wallCols.numWalls - 1];
    119                 wallAngle = atan2s(wall->normal.z, wall->normal.x);
    120                 wallDYaw = wallAngle - m->faceAngle[1];
    121 
    122                 if (wallDYaw > -0x4000 && wallDYaw < 0x4000) {
    123                     m->pos[0] = wallCols.x - 20.0f * wall->normal.x;
    124                     m->pos[2] = wallCols.z - 20.0f * wall->normal.z;
    125 
    126                     m->faceAngle[0] = 0;
    127                     m->faceAngle[1] = wallAngle + 0x8000;
    128 
    129                     set_mario_action(m, ACT_LEDGE_CLIMB_DOWN, 0);
    130                     set_mario_animation(m, MARIO_ANIM_CLIMB_DOWN_LEDGE);
    131                 }
    132             }
    133         }
    134     }
    135 }
    136 
    137 void slide_bonk(struct MarioState *m, u32 fastAction, u32 slowAction) {
    138     if (m->forwardVel > 16.0f) {
    139         mario_bonk_reflection(m, TRUE);
    140         drop_and_set_mario_action(m, fastAction, 0);
    141     } else {
    142         mario_set_forward_vel(m, 0.0f);
    143         set_mario_action(m, slowAction, 0);
    144     }
    145 }
    146 
    147 s32 set_triple_jump_action(struct MarioState *m, UNUSED u32 action, UNUSED u32 actionArg) {
    148     if (m->flags & MARIO_WING_CAP) {
    149         return set_mario_action(m, ACT_FLYING_TRIPLE_JUMP, 0);
    150     } else if (m->forwardVel > 20.0f) {
    151         return set_mario_action(m, ACT_TRIPLE_JUMP, 0);
    152     } else {
    153         return set_mario_action(m, ACT_JUMP, 0);
    154     }
    155 
    156     return FALSE;
    157 }
    158 
    159 void update_sliding_angle(struct MarioState *m, f32 accel, f32 lossFactor) {
    160     s32 newFacingDYaw;
    161     s16 facingDYaw;
    162 
    163     struct Surface *floor = m->floor;
    164     s16 slopeAngle = atan2s(floor->normal.z, floor->normal.x);
    165     f32 steepness = sqrtf(floor->normal.x * floor->normal.x + floor->normal.z * floor->normal.z);
    166     UNUSED f32 normalY = floor->normal.y;
    167 
    168     m->slideVelX += accel * steepness * sins(slopeAngle);
    169     m->slideVelZ += accel * steepness * coss(slopeAngle);
    170 
    171     m->slideVelX *= lossFactor;
    172     m->slideVelZ *= lossFactor;
    173 
    174     m->slideYaw = atan2s(m->slideVelZ, m->slideVelX);
    175 
    176     facingDYaw = m->faceAngle[1] - m->slideYaw;
    177     newFacingDYaw = facingDYaw;
    178 
    179     //! -0x4000 not handled - can slide down a slope while facing perpendicular to it
    180     if (newFacingDYaw > 0 && newFacingDYaw <= 0x4000) {
    181         if ((newFacingDYaw -= 0x200) < 0) {
    182             newFacingDYaw = 0;
    183         }
    184     } else if (newFacingDYaw > -0x4000 && newFacingDYaw < 0) {
    185         if ((newFacingDYaw += 0x200) > 0) {
    186             newFacingDYaw = 0;
    187         }
    188     } else if (newFacingDYaw > 0x4000 && newFacingDYaw < 0x8000) {
    189         if ((newFacingDYaw += 0x200) > 0x8000) {
    190             newFacingDYaw = 0x8000;
    191         }
    192     } else if (newFacingDYaw > -0x8000 && newFacingDYaw < -0x4000) {
    193         if ((newFacingDYaw -= 0x200) < -0x8000) {
    194             newFacingDYaw = -0x8000;
    195         }
    196     }
    197 
    198     m->faceAngle[1] = m->slideYaw + newFacingDYaw;
    199 
    200     m->vel[0] = m->slideVelX;
    201     m->vel[1] = 0.0f;
    202     m->vel[2] = m->slideVelZ;
    203 
    204     mario_update_moving_sand(m);
    205     mario_update_windy_ground(m);
    206 
    207     //! Speed is capped a frame late (butt slide HSG)
    208     m->forwardVel = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
    209     if (m->forwardVel > 100.0f) {
    210         m->slideVelX = m->slideVelX * 100.0f / m->forwardVel;
    211         m->slideVelZ = m->slideVelZ * 100.0f / m->forwardVel;
    212     }
    213 
    214     if (newFacingDYaw < -0x4000 || newFacingDYaw > 0x4000) {
    215         m->forwardVel *= -1.0f;
    216     }
    217 }
    218 
    219 s32 update_sliding(struct MarioState *m, f32 stopSpeed) {
    220     f32 lossFactor;
    221     f32 accel;
    222     f32 oldSpeed;
    223     f32 newSpeed;
    224 
    225     s32 stopped = FALSE;
    226 
    227     s16 intendedDYaw = m->intendedYaw - m->slideYaw;
    228     f32 forward = coss(intendedDYaw);
    229     f32 sideward = sins(intendedDYaw);
    230 
    231     //! 10k glitch
    232     if (forward < 0.0f && m->forwardVel >= 0.0f) {
    233         forward *= 0.5f + 0.5f * m->forwardVel / 100.0f;
    234     }
    235 
    236     switch (mario_get_floor_class(m)) {
    237         case SURFACE_CLASS_VERY_SLIPPERY:
    238             accel = 10.0f;
    239             lossFactor = m->intendedMag / 32.0f * forward * 0.02f + 0.98f;
    240             break;
    241 
    242         case SURFACE_CLASS_SLIPPERY:
    243             accel = 8.0f;
    244             lossFactor = m->intendedMag / 32.0f * forward * 0.02f + 0.96f;
    245             break;
    246 
    247         default:
    248             accel = 7.0f;
    249             lossFactor = m->intendedMag / 32.0f * forward * 0.02f + 0.92f;
    250             break;
    251 
    252         case SURFACE_CLASS_NOT_SLIPPERY:
    253             accel = 5.0f;
    254             lossFactor = m->intendedMag / 32.0f * forward * 0.02f + 0.92f;
    255             break;
    256     }
    257 
    258     oldSpeed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
    259 
    260     //! This is attempting to use trig derivatives to rotate Mario's speed.
    261     // It is slightly off/asymmetric since it uses the new X speed, but the old
    262     // Z speed.
    263     m->slideVelX += m->slideVelZ * (m->intendedMag / 32.0f) * sideward * 0.05f;
    264     m->slideVelZ -= m->slideVelX * (m->intendedMag / 32.0f) * sideward * 0.05f;
    265 
    266     newSpeed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
    267 
    268     if (oldSpeed > 0.0f && newSpeed > 0.0f) {
    269         m->slideVelX = m->slideVelX * oldSpeed / newSpeed;
    270         m->slideVelZ = m->slideVelZ * oldSpeed / newSpeed;
    271     }
    272 
    273     update_sliding_angle(m, accel, lossFactor);
    274 
    275     if (!mario_floor_is_slope(m) && m->forwardVel * m->forwardVel < stopSpeed * stopSpeed) {
    276         mario_set_forward_vel(m, 0.0f);
    277         stopped = TRUE;
    278     }
    279 
    280     return stopped;
    281 }
    282 
    283 void apply_slope_accel(struct MarioState *m) {
    284     f32 slopeAccel;
    285 
    286     struct Surface *floor = m->floor;
    287     f32 steepness = sqrtf(floor->normal.x * floor->normal.x + floor->normal.z * floor->normal.z);
    288 
    289     UNUSED f32 normalY = floor->normal.y;
    290     s16 floorDYaw = m->floorAngle - m->faceAngle[1];
    291 
    292     if (mario_floor_is_slope(m)) {
    293         s16 slopeClass = 0;
    294 
    295         if (m->action != ACT_SOFT_BACKWARD_GROUND_KB && m->action != ACT_SOFT_FORWARD_GROUND_KB) {
    296             slopeClass = mario_get_floor_class(m);
    297         }
    298 
    299         switch (slopeClass) {
    300             case SURFACE_CLASS_VERY_SLIPPERY:
    301                 slopeAccel = 5.3f;
    302                 break;
    303             case SURFACE_CLASS_SLIPPERY:
    304                 slopeAccel = 2.7f;
    305                 break;
    306             default:
    307                 slopeAccel = 1.7f;
    308                 break;
    309             case SURFACE_CLASS_NOT_SLIPPERY:
    310                 slopeAccel = 0.0f;
    311                 break;
    312         }
    313 
    314         if (floorDYaw > -0x4000 && floorDYaw < 0x4000) {
    315             m->forwardVel += slopeAccel * steepness;
    316         } else {
    317             m->forwardVel -= slopeAccel * steepness;
    318         }
    319     }
    320 
    321     m->slideYaw = m->faceAngle[1];
    322 
    323     m->slideVelX = m->forwardVel * sins(m->faceAngle[1]);
    324     m->slideVelZ = m->forwardVel * coss(m->faceAngle[1]);
    325 
    326     m->vel[0] = m->slideVelX;
    327     m->vel[1] = 0.0f;
    328     m->vel[2] = m->slideVelZ;
    329 
    330     mario_update_moving_sand(m);
    331     mario_update_windy_ground(m);
    332 }
    333 
    334 s32 apply_landing_accel(struct MarioState *m, f32 frictionFactor) {
    335     s32 stopped = FALSE;
    336 
    337     apply_slope_accel(m);
    338 
    339     if (!mario_floor_is_slope(m)) {
    340         m->forwardVel *= frictionFactor;
    341         if (m->forwardVel * m->forwardVel < 1.0f) {
    342             mario_set_forward_vel(m, 0.0f);
    343             stopped = TRUE;
    344         }
    345     }
    346 
    347     return stopped;
    348 }
    349 
    350 void update_shell_speed(struct MarioState *m) {
    351     f32 maxTargetSpeed;
    352     f32 targetSpeed;
    353 
    354     if (m->floorHeight < m->waterLevel) {
    355         m->floorHeight = m->waterLevel;
    356         m->floor = &gWaterSurfacePseudoFloor;
    357         m->floor->originOffset = m->waterLevel; //! Negative origin offset
    358     }
    359 
    360     if (m->floor != NULL && m->floor->type == SURFACE_SLOW) {
    361         maxTargetSpeed = 48.0f;
    362     } else {
    363         maxTargetSpeed = 64.0f;
    364     }
    365 
    366     targetSpeed = m->intendedMag * 2.0f;
    367     if (targetSpeed > maxTargetSpeed) {
    368         targetSpeed = maxTargetSpeed;
    369     }
    370     if (targetSpeed < 24.0f) {
    371         targetSpeed = 24.0f;
    372     }
    373 
    374     if (m->forwardVel <= 0.0f) {
    375         m->forwardVel += 1.1f;
    376     } else if (m->forwardVel <= targetSpeed) {
    377         m->forwardVel += 1.1f - m->forwardVel / 58.0f;
    378     } else if (m->floor->normal.y >= 0.95f) {
    379         m->forwardVel -= 1.0f;
    380     }
    381 
    382     //! No backward speed cap (shell hyperspeed)
    383     if (m->forwardVel > 64.0f) {
    384         m->forwardVel = 64.0f;
    385     }
    386 
    387     m->faceAngle[1] =
    388         m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
    389 
    390     apply_slope_accel(m);
    391 }
    392 
    393 s32 apply_slope_decel(struct MarioState *m, f32 decelCoef) {
    394     f32 decel;
    395     s32 stopped = FALSE;
    396 
    397     switch (mario_get_floor_class(m)) {
    398         case SURFACE_CLASS_VERY_SLIPPERY:
    399             decel = decelCoef * 0.2f;
    400             break;
    401         case SURFACE_CLASS_SLIPPERY:
    402             decel = decelCoef * 0.7f;
    403             break;
    404         default:
    405             decel = decelCoef * 2.0f;
    406             break;
    407         case SURFACE_CLASS_NOT_SLIPPERY:
    408             decel = decelCoef * 3.0f;
    409             break;
    410     }
    411 
    412     if ((m->forwardVel = approach_f32(m->forwardVel, 0.0f, decel, decel)) == 0.0f) {
    413         stopped = TRUE;
    414     }
    415 
    416     apply_slope_accel(m);
    417     return stopped;
    418 }
    419 
    420 s32 update_decelerating_speed(struct MarioState *m) {
    421     s32 stopped = FALSE;
    422 
    423     if ((m->forwardVel = approach_f32(m->forwardVel, 0.0f, 1.0f, 1.0f)) == 0.0f) {
    424         stopped = TRUE;
    425     }
    426 
    427     mario_set_forward_vel(m, m->forwardVel);
    428     mario_update_moving_sand(m);
    429     mario_update_windy_ground(m);
    430 
    431     return stopped;
    432 }
    433 
    434 void update_walking_speed(struct MarioState *m) {
    435     f32 maxTargetSpeed;
    436     f32 targetSpeed;
    437 
    438     if (m->floor != NULL && m->floor->type == SURFACE_SLOW) {
    439         maxTargetSpeed = 24.0f;
    440     } else {
    441         maxTargetSpeed = 32.0f;
    442     }
    443 
    444     targetSpeed = m->intendedMag < maxTargetSpeed ? m->intendedMag : maxTargetSpeed;
    445 
    446     if (m->quicksandDepth > 10.0f) {
    447         targetSpeed *= 6.25 / m->quicksandDepth;
    448     }
    449 
    450     if (m->forwardVel <= 0.0f) {
    451         m->forwardVel += 1.1f;
    452     } else if (m->forwardVel <= targetSpeed) {
    453         m->forwardVel += 1.1f - m->forwardVel / 43.0f;
    454     } else if (m->floor->normal.y >= 0.95f) {
    455         m->forwardVel -= 1.0f;
    456     }
    457 
    458     if (m->forwardVel > 48.0f) {
    459         m->forwardVel = 48.0f;
    460     }
    461 
    462     m->faceAngle[1] =
    463         m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x800, 0x800);
    464     apply_slope_accel(m);
    465 }
    466 
    467 s32 should_begin_sliding(struct MarioState *m) {
    468     if (m->input & INPUT_ABOVE_SLIDE) {
    469         s32 slideLevel = (m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE;
    470         s32 movingBackward = m->forwardVel <= -1.0f;
    471 
    472         if (slideLevel || movingBackward || mario_facing_downhill(m, FALSE)) {
    473             return TRUE;
    474         }
    475     }
    476 
    477     return FALSE;
    478 }
    479 
    480 s32 analog_stick_held_back(struct MarioState *m) {
    481     s16 intendedDYaw = m->intendedYaw - m->faceAngle[1];
    482     return intendedDYaw < -0x471C || intendedDYaw > 0x471C;
    483 }
    484 
    485 s32 check_ground_dive_or_punch(struct MarioState *m) {
    486     UNUSED u8 filler[4];
    487 
    488     if (m->input & INPUT_B_PRESSED) {
    489         //! Speed kick (shoutouts to SimpleFlips)
    490         if (m->forwardVel >= 29.0f && m->controller->stickMag > 48.0f) {
    491             m->vel[1] = 20.0f;
    492             return set_mario_action(m, ACT_DIVE, 1);
    493         }
    494 
    495         return set_mario_action(m, ACT_MOVE_PUNCHING, 0);
    496     }
    497 
    498     return FALSE;
    499 }
    500 
    501 s32 begin_braking_action(struct MarioState *m) {
    502     mario_drop_held_object(m);
    503 
    504     if (m->actionState == 1) {
    505         m->faceAngle[1] = m->actionArg;
    506         return set_mario_action(m, ACT_STANDING_AGAINST_WALL, 0);
    507     }
    508 
    509     if (m->forwardVel >= 16.0f && m->floor->normal.y >= 0.17364818f) {
    510         return set_mario_action(m, ACT_BRAKING, 0);
    511     }
    512 
    513     return set_mario_action(m, ACT_DECELERATING, 0);
    514 }
    515 
    516 void anim_and_audio_for_walk(struct MarioState *m) {
    517     s32 val14;
    518     struct Object *marioObj = m->marioObj;
    519     s32 val0C = TRUE;
    520     s16 targetPitch = 0;
    521     f32 val04;
    522 
    523     val04 = m->intendedMag > m->forwardVel ? m->intendedMag : m->forwardVel;
    524 
    525     if (val04 < 4.0f) {
    526         val04 = 4.0f;
    527     }
    528 
    529     if (m->quicksandDepth > 50.0f) {
    530         val14 = (s32)(val04 / 4.0f * 0x10000);
    531         set_mario_anim_with_accel(m, MARIO_ANIM_MOVE_IN_QUICKSAND, val14);
    532         play_step_sound(m, 19, 93);
    533         m->actionTimer = 0;
    534     } else {
    535         while (val0C) {
    536             switch (m->actionTimer) {
    537                 case 0:
    538                     if (val04 > 8.0f) {
    539                         m->actionTimer = 2;
    540                     } else {
    541                         //! (Speed Crash) If Mario's speed is more than 2^17.
    542                         if ((val14 = (s32)(val04 / 4.0f * 0x10000)) < 0x1000) {
    543                             val14 = 0x1000;
    544                         }
    545                         set_mario_anim_with_accel(m, MARIO_ANIM_START_TIPTOE, val14);
    546                         play_step_sound(m, 7, 22);
    547                         if (is_anim_past_frame(m, 23)) {
    548                             m->actionTimer = 2;
    549                         }
    550 
    551                         val0C = FALSE;
    552                     }
    553                     break;
    554 
    555                 case 1:
    556                     if (val04 > 8.0f) {
    557                         m->actionTimer = 2;
    558                     } else {
    559                         //! (Speed Crash) If Mario's speed is more than 2^17.
    560                         if ((val14 = (s32)(val04 * 0x10000)) < 0x1000) {
    561                             val14 = 0x1000;
    562                         }
    563                         set_mario_anim_with_accel(m, MARIO_ANIM_TIPTOE, val14);
    564                         play_step_sound(m, 14, 72);
    565 
    566                         val0C = FALSE;
    567                     }
    568                     break;
    569 
    570                 case 2:
    571                     if (val04 < 5.0f) {
    572                         m->actionTimer = 1;
    573                     } else if (val04 > 22.0f) {
    574                         m->actionTimer = 3;
    575                     } else {
    576                         //! (Speed Crash) If Mario's speed is more than 2^17.
    577                         val14 = (s32)(val04 / 4.0f * 0x10000);
    578                         set_mario_anim_with_accel(m, MARIO_ANIM_WALKING, val14);
    579                         play_step_sound(m, 10, 49);
    580 
    581                         val0C = FALSE;
    582                     }
    583                     break;
    584 
    585                 case 3:
    586                     if (val04 < 18.0f) {
    587                         m->actionTimer = 2;
    588                     } else {
    589                         //! (Speed Crash) If Mario's speed is more than 2^17.
    590                         val14 = (s32)(val04 / 4.0f * 0x10000);
    591                         set_mario_anim_with_accel(m, MARIO_ANIM_RUNNING, val14);
    592                         play_step_sound(m, 9, 45);
    593                         targetPitch = tilt_body_running(m);
    594 
    595                         val0C = FALSE;
    596                     }
    597                     break;
    598             }
    599         }
    600     }
    601 
    602     marioObj->oMarioWalkingPitch =
    603         (s16) approach_s32(marioObj->oMarioWalkingPitch, targetPitch, 0x800, 0x800);
    604     marioObj->header.gfx.angle[0] = marioObj->oMarioWalkingPitch;
    605 }
    606 
    607 void anim_and_audio_for_hold_walk(struct MarioState *m) {
    608     s32 val0C;
    609     s32 val08 = TRUE;
    610     f32 val04;
    611 
    612     val04 = m->intendedMag > m->forwardVel ? m->intendedMag : m->forwardVel;
    613 
    614     if (val04 < 2.0f) {
    615         val04 = 2.0f;
    616     }
    617 
    618     while (val08) {
    619         switch (m->actionTimer) {
    620             case 0:
    621                 if (val04 > 6.0f) {
    622                     m->actionTimer = 1;
    623                 } else {
    624                     //! (Speed Crash) Crashes if Mario's speed exceeds or equals 2^15.
    625                     val0C = (s32)(val04 * 0x10000);
    626                     set_mario_anim_with_accel(m, MARIO_ANIM_SLOW_WALK_WITH_LIGHT_OBJ, val0C);
    627                     play_step_sound(m, 12, 62);
    628 
    629                     val08 = FALSE;
    630                 }
    631                 break;
    632 
    633             case 1:
    634                 if (val04 < 3.0f) {
    635                     m->actionTimer = 0;
    636                 } else if (val04 > 11.0f) {
    637                     m->actionTimer = 2;
    638                 } else {
    639                     //! (Speed Crash) Crashes if Mario's speed exceeds or equals 2^15.
    640                     val0C = (s32)(val04 * 0x10000);
    641                     set_mario_anim_with_accel(m, MARIO_ANIM_WALK_WITH_LIGHT_OBJ, val0C);
    642                     play_step_sound(m, 12, 62);
    643 
    644                     val08 = FALSE;
    645                 }
    646                 break;
    647 
    648             case 2:
    649                 if (val04 < 8.0f) {
    650                     m->actionTimer = 1;
    651                 } else {
    652                     //! (Speed Crash) Crashes if Mario's speed exceeds or equals 2^16.
    653                     val0C = (s32)(val04 / 2.0f * 0x10000);
    654                     set_mario_anim_with_accel(m, MARIO_ANIM_RUN_WITH_LIGHT_OBJ, val0C);
    655                     play_step_sound(m, 10, 49);
    656 
    657                     val08 = FALSE;
    658                 }
    659                 break;
    660         }
    661     }
    662 }
    663 
    664 void anim_and_audio_for_heavy_walk(struct MarioState *m) {
    665     s32 val04 = (s32)(m->intendedMag * 0x10000);
    666     set_mario_anim_with_accel(m, MARIO_ANIM_WALK_WITH_HEAVY_OBJ, val04);
    667     play_step_sound(m, 26, 79);
    668 }
    669 
    670 void push_or_sidle_wall(struct MarioState *m, Vec3f startPos) {
    671     s16 wallAngle;
    672     s16 dWallAngle;
    673     f32 dx = m->pos[0] - startPos[0];
    674     f32 dz = m->pos[2] - startPos[2];
    675     f32 movedDistance = sqrtf(dx * dx + dz * dz);
    676     //! (Speed Crash) If a wall is after moving 16384 distance, this crashes.
    677     s32 val04 = (s32)(movedDistance * 2.0f * 0x10000);
    678 
    679     if (m->forwardVel > 6.0f) {
    680         mario_set_forward_vel(m, 6.0f);
    681     }
    682 
    683     if (m->wall != NULL) {
    684         wallAngle = atan2s(m->wall->normal.z, m->wall->normal.x);
    685         dWallAngle = wallAngle - m->faceAngle[1];
    686     }
    687 
    688     if (m->wall == NULL || dWallAngle <= -0x71C8 || dWallAngle >= 0x71C8) {
    689         m->flags |= MARIO_UNKNOWN_31;
    690         set_mario_animation(m, MARIO_ANIM_PUSHING);
    691         play_step_sound(m, 6, 18);
    692     } else {
    693         if (dWallAngle < 0) {
    694             set_mario_anim_with_accel(m, MARIO_ANIM_SIDESTEP_RIGHT, val04);
    695         } else {
    696             set_mario_anim_with_accel(m, MARIO_ANIM_SIDESTEP_LEFT, val04);
    697         }
    698 
    699         if (m->marioObj->header.gfx.animInfo.animFrame < 20) {
    700             play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
    701             m->particleFlags |= PARTICLE_DUST;
    702         }
    703 
    704         m->actionState = 1;
    705         m->actionArg = wallAngle + 0x8000;
    706         m->marioObj->header.gfx.angle[1] = wallAngle + 0x8000;
    707         m->marioObj->header.gfx.angle[2] = find_floor_slope(m, 0x4000);
    708     }
    709 }
    710 
    711 void tilt_body_walking(struct MarioState *m, s16 startYaw) {
    712     struct MarioBodyState *val0C = m->marioBodyState;
    713     UNUSED struct Object *marioObj = m->marioObj;
    714     s16 animID = m->marioObj->header.gfx.animInfo.animID;
    715 
    716     if (animID == MARIO_ANIM_WALKING || animID == MARIO_ANIM_RUNNING) {
    717         s16 dYaw = m->faceAngle[1] - startYaw;
    718         //! (Speed Crash) These casts can cause a crash if (dYaw * forwardVel / 12) or
    719         //! (forwardVel * 170) exceed or equal 2^31.
    720         s16 val02 = -(s16)(dYaw * m->forwardVel / 12.0f);
    721         s16 val00 = (s16)(m->forwardVel * 170.0f);
    722 
    723         if (val02 > 0x1555) {
    724             val02 = 0x1555;
    725         }
    726         if (val02 < -0x1555) {
    727             val02 = -0x1555;
    728         }
    729 
    730         if (val00 > 0x1555) {
    731             val00 = 0x1555;
    732         }
    733         if (val00 < 0) {
    734             val00 = 0;
    735         }
    736 
    737         val0C->torsoAngle[2] = approach_s32(val0C->torsoAngle[2], val02, 0x400, 0x400);
    738         val0C->torsoAngle[0] = approach_s32(val0C->torsoAngle[0], val00, 0x400, 0x400);
    739     } else {
    740         val0C->torsoAngle[2] = 0;
    741         val0C->torsoAngle[0] = 0;
    742     }
    743 }
    744 
    745 void tilt_body_ground_shell(struct MarioState *m, s16 startYaw) {
    746     struct MarioBodyState *val0C = m->marioBodyState;
    747     struct Object *marioObj = m->marioObj;
    748     s16 dYaw = m->faceAngle[1] - startYaw;
    749     //! (Speed Crash) These casts can cause a crash if (dYaw * forwardVel / 12) or
    750     //! (forwardVel * 170) exceed or equal 2^31. Harder (if not impossible to do)
    751     //! while on a Koopa Shell making this less of an issue.
    752     s16 val04 = -(s16)(dYaw * m->forwardVel / 12.0f);
    753     s16 val02 = (s16)(m->forwardVel * 170.0f);
    754 
    755     if (val04 > 0x1800) {
    756         val04 = 0x1800;
    757     }
    758     if (val04 < -0x1800) {
    759         val04 = -0x1800;
    760     }
    761 
    762     if (val02 > 0x1000) {
    763         val02 = 0x1000;
    764     }
    765     if (val02 < 0) {
    766         val02 = 0;
    767     }
    768 
    769     val0C->torsoAngle[2] = approach_s32(val0C->torsoAngle[2], val04, 0x200, 0x200);
    770     val0C->torsoAngle[0] = approach_s32(val0C->torsoAngle[0], val02, 0x200, 0x200);
    771     val0C->headAngle[2] = -val0C->torsoAngle[2];
    772 
    773     marioObj->header.gfx.angle[2] = val0C->torsoAngle[2];
    774     marioObj->header.gfx.pos[1] += 45.0f;
    775 }
    776 
    777 s32 act_walking(struct MarioState *m) {
    778     Vec3f startPos;
    779     s16 startYaw = m->faceAngle[1];
    780 
    781     mario_drop_held_object(m);
    782 
    783     if (should_begin_sliding(m)) {
    784         return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
    785     }
    786 
    787     if (m->input & INPUT_FIRST_PERSON) {
    788         return begin_braking_action(m);
    789     }
    790 
    791     if (m->input & INPUT_A_PRESSED) {
    792         return set_jump_from_landing(m);
    793     }
    794 
    795     if (check_ground_dive_or_punch(m)) {
    796         return TRUE;
    797     }
    798 
    799     if (m->input & INPUT_UNKNOWN_5) {
    800         return begin_braking_action(m);
    801     }
    802 
    803     if (analog_stick_held_back(m) && m->forwardVel >= 16.0f) {
    804         return set_mario_action(m, ACT_TURNING_AROUND, 0);
    805     }
    806 
    807     if (m->input & INPUT_Z_PRESSED) {
    808         return set_mario_action(m, ACT_CROUCH_SLIDE, 0);
    809     }
    810 
    811     m->actionState = 0;
    812 
    813     vec3f_copy(startPos, m->pos);
    814     update_walking_speed(m);
    815 
    816     switch (perform_ground_step(m)) {
    817         case GROUND_STEP_LEFT_GROUND:
    818             set_mario_action(m, ACT_FREEFALL, 0);
    819             set_mario_animation(m, MARIO_ANIM_GENERAL_FALL);
    820             break;
    821 
    822         case GROUND_STEP_NONE:
    823             anim_and_audio_for_walk(m);
    824             if (m->intendedMag - m->forwardVel > 16.0f) {
    825                 m->particleFlags |= PARTICLE_DUST;
    826             }
    827             break;
    828 
    829         case GROUND_STEP_HIT_WALL:
    830             push_or_sidle_wall(m, startPos);
    831             m->actionTimer = 0;
    832             break;
    833     }
    834 
    835     check_ledge_climb_down(m);
    836     tilt_body_walking(m, startYaw);
    837     return FALSE;
    838 }
    839 
    840 s32 act_move_punching(struct MarioState *m) {
    841     if (should_begin_sliding(m)) {
    842         return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
    843     }
    844 
    845     if (m->actionState == 0 && (m->input & INPUT_A_DOWN)) {
    846         return set_mario_action(m, ACT_JUMP_KICK, 0);
    847     }
    848 
    849     m->actionState = 1;
    850 
    851     mario_update_punch_sequence(m);
    852 
    853     if (m->forwardVel >= 0.0f) {
    854         apply_slope_decel(m, 0.5f);
    855     } else {
    856         if ((m->forwardVel += 8.0f) >= 0.0f) {
    857             m->forwardVel = 0.0f;
    858         }
    859         apply_slope_accel(m);
    860     }
    861 
    862     switch (perform_ground_step(m)) {
    863         case GROUND_STEP_LEFT_GROUND:
    864             set_mario_action(m, ACT_FREEFALL, 0);
    865             break;
    866 
    867         case GROUND_STEP_NONE:
    868             m->particleFlags |= PARTICLE_DUST;
    869             break;
    870     }
    871 
    872     return FALSE;
    873 }
    874 
    875 s32 act_hold_walking(struct MarioState *m) {
    876     if (m->heldObj->behavior == segmented_to_virtual(bhvJumpingBox)) {
    877         return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0);
    878     }
    879 
    880     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
    881         return drop_and_set_mario_action(m, ACT_WALKING, 0);
    882     }
    883 
    884     if (should_begin_sliding(m)) {
    885         return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0);
    886     }
    887 
    888     if (m->input & INPUT_B_PRESSED) {
    889         return set_mario_action(m, ACT_THROWING, 0);
    890     }
    891 
    892     if (m->input & INPUT_A_PRESSED) {
    893         return set_jumping_action(m, ACT_HOLD_JUMP, 0);
    894     }
    895 
    896     if (m->input & INPUT_UNKNOWN_5) {
    897         return set_mario_action(m, ACT_HOLD_DECELERATING, 0);
    898     }
    899 
    900     if (m->input & INPUT_Z_PRESSED) {
    901         return drop_and_set_mario_action(m, ACT_CROUCH_SLIDE, 0);
    902     }
    903 
    904     m->intendedMag *= 0.4f;
    905 
    906     update_walking_speed(m);
    907 
    908     switch (perform_ground_step(m)) {
    909         case GROUND_STEP_LEFT_GROUND:
    910             set_mario_action(m, ACT_HOLD_FREEFALL, 0);
    911             break;
    912 
    913         case GROUND_STEP_HIT_WALL:
    914             if (m->forwardVel > 16.0f) {
    915                 mario_set_forward_vel(m, 16.0f);
    916             }
    917             break;
    918     }
    919 
    920     anim_and_audio_for_hold_walk(m);
    921 
    922     if (0.4f * m->intendedMag - m->forwardVel > 10.0f) {
    923         m->particleFlags |= PARTICLE_DUST;
    924     }
    925 
    926     return FALSE;
    927 }
    928 
    929 s32 act_hold_heavy_walking(struct MarioState *m) {
    930     if (m->input & INPUT_B_PRESSED) {
    931         return set_mario_action(m, ACT_HEAVY_THROW, 0);
    932     }
    933 
    934     if (should_begin_sliding(m)) {
    935         return drop_and_set_mario_action(m, ACT_BEGIN_SLIDING, 0);
    936     }
    937 
    938     if (m->input & INPUT_UNKNOWN_5) {
    939         return set_mario_action(m, ACT_HOLD_HEAVY_IDLE, 0);
    940     }
    941 
    942     m->intendedMag *= 0.1f;
    943 
    944     update_walking_speed(m);
    945 
    946     switch (perform_ground_step(m)) {
    947         case GROUND_STEP_LEFT_GROUND:
    948             drop_and_set_mario_action(m, ACT_FREEFALL, 0);
    949             break;
    950 
    951         case GROUND_STEP_HIT_WALL:
    952             if (m->forwardVel > 10.0f) {
    953                 mario_set_forward_vel(m, 10.0f);
    954             }
    955             break;
    956     }
    957 
    958     anim_and_audio_for_heavy_walk(m);
    959     return FALSE;
    960 }
    961 
    962 s32 act_turning_around(struct MarioState *m) {
    963     if (m->input & INPUT_ABOVE_SLIDE) {
    964         return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
    965     }
    966 
    967     if (m->input & INPUT_A_PRESSED) {
    968         return set_jumping_action(m, ACT_SIDE_FLIP, 0);
    969     }
    970 
    971     if (m->input & INPUT_UNKNOWN_5) {
    972         return set_mario_action(m, ACT_BRAKING, 0);
    973     }
    974 
    975     if (!analog_stick_held_back(m)) {
    976         return set_mario_action(m, ACT_WALKING, 0);
    977     }
    978 
    979     if (apply_slope_decel(m, 2.0f)) {
    980         return begin_walking_action(m, 8.0f, ACT_FINISH_TURNING_AROUND, 0);
    981     }
    982 
    983     play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
    984 
    985     adjust_sound_for_speed(m);
    986 
    987     switch (perform_ground_step(m)) {
    988         case GROUND_STEP_LEFT_GROUND:
    989             set_mario_action(m, ACT_FREEFALL, 0);
    990             break;
    991 
    992         case GROUND_STEP_NONE:
    993             m->particleFlags |= PARTICLE_DUST;
    994             break;
    995     }
    996 
    997     if (m->forwardVel >= 18.0f) {
    998         set_mario_animation(m, MARIO_ANIM_TURNING_PART1);
    999     } else {
   1000         set_mario_animation(m, MARIO_ANIM_TURNING_PART2);
   1001         if (is_anim_at_end(m)) {
   1002             if (m->forwardVel > 0.0f) {
   1003                 begin_walking_action(m, -m->forwardVel, ACT_WALKING, 0);
   1004             } else {
   1005                 begin_walking_action(m, 8.0f, ACT_WALKING, 0);
   1006             }
   1007         }
   1008     }
   1009 
   1010     return FALSE;
   1011 }
   1012 
   1013 s32 act_finish_turning_around(struct MarioState *m) {
   1014     if (m->input & INPUT_ABOVE_SLIDE) {
   1015         return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
   1016     }
   1017 
   1018     if (m->input & INPUT_A_PRESSED) {
   1019         return set_jumping_action(m, ACT_SIDE_FLIP, 0);
   1020     }
   1021 
   1022     update_walking_speed(m);
   1023     set_mario_animation(m, MARIO_ANIM_TURNING_PART2);
   1024 
   1025     if (perform_ground_step(m) == GROUND_STEP_LEFT_GROUND) {
   1026         set_mario_action(m, ACT_FREEFALL, 0);
   1027     }
   1028 
   1029     if (is_anim_at_end(m)) {
   1030         set_mario_action(m, ACT_WALKING, 0);
   1031     }
   1032 
   1033     m->marioObj->header.gfx.angle[1] += 0x8000;
   1034     return FALSE;
   1035 }
   1036 
   1037 s32 act_braking(struct MarioState *m) {
   1038     if (!(m->input & INPUT_FIRST_PERSON)
   1039         && (m->input
   1040             & (INPUT_NONZERO_ANALOG | INPUT_A_PRESSED | INPUT_OFF_FLOOR | INPUT_ABOVE_SLIDE))) {
   1041         return check_common_action_exits(m);
   1042     }
   1043 
   1044     if (apply_slope_decel(m, 2.0f)) {
   1045         return set_mario_action(m, ACT_BRAKING_STOP, 0);
   1046     }
   1047 
   1048     if (m->input & INPUT_B_PRESSED) {
   1049         return set_mario_action(m, ACT_MOVE_PUNCHING, 0);
   1050     }
   1051 
   1052     switch (perform_ground_step(m)) {
   1053         case GROUND_STEP_LEFT_GROUND:
   1054             set_mario_action(m, ACT_FREEFALL, 0);
   1055             break;
   1056 
   1057         case GROUND_STEP_NONE:
   1058             m->particleFlags |= PARTICLE_DUST;
   1059             break;
   1060 
   1061         case GROUND_STEP_HIT_WALL:
   1062             slide_bonk(m, ACT_BACKWARD_GROUND_KB, ACT_BRAKING_STOP);
   1063             break;
   1064     }
   1065 
   1066     play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
   1067     adjust_sound_for_speed(m);
   1068     set_mario_animation(m, MARIO_ANIM_SKID_ON_GROUND);
   1069     return FALSE;
   1070 }
   1071 
   1072 s32 act_decelerating(struct MarioState *m) {
   1073     s32 val0C;
   1074     s16 slopeClass = mario_get_floor_class(m);
   1075 
   1076     if (!(m->input & INPUT_FIRST_PERSON)) {
   1077         if (should_begin_sliding(m)) {
   1078             return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
   1079         }
   1080 
   1081         if (m->input & INPUT_A_PRESSED) {
   1082             return set_jump_from_landing(m);
   1083         }
   1084 
   1085         if (check_ground_dive_or_punch(m)) {
   1086             return TRUE;
   1087         }
   1088 
   1089         if (m->input & INPUT_NONZERO_ANALOG) {
   1090             return set_mario_action(m, ACT_WALKING, 0);
   1091         }
   1092 
   1093         if (m->input & INPUT_Z_PRESSED) {
   1094             return set_mario_action(m, ACT_CROUCH_SLIDE, 0);
   1095         }
   1096     }
   1097 
   1098     if (update_decelerating_speed(m)) {
   1099         return set_mario_action(m, ACT_IDLE, 0);
   1100     }
   1101 
   1102     switch (perform_ground_step(m)) {
   1103         case GROUND_STEP_LEFT_GROUND:
   1104             set_mario_action(m, ACT_FREEFALL, 0);
   1105             break;
   1106 
   1107         case GROUND_STEP_HIT_WALL:
   1108             if (slopeClass == SURFACE_CLASS_VERY_SLIPPERY) {
   1109                 mario_bonk_reflection(m, TRUE);
   1110             } else {
   1111                 mario_set_forward_vel(m, 0.0f);
   1112             }
   1113             break;
   1114     }
   1115 
   1116     if (slopeClass == SURFACE_CLASS_VERY_SLIPPERY) {
   1117         set_mario_animation(m, MARIO_ANIM_IDLE_HEAD_LEFT);
   1118         play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
   1119         adjust_sound_for_speed(m);
   1120         m->particleFlags |= PARTICLE_DUST;
   1121     } else {
   1122         // (Speed Crash) Crashes if speed exceeds 2^17.
   1123         if ((val0C = (s32)(m->forwardVel / 4.0f * 0x10000)) < 0x1000) {
   1124             val0C = 0x1000;
   1125         }
   1126 
   1127         set_mario_anim_with_accel(m, MARIO_ANIM_WALKING, val0C);
   1128         play_step_sound(m, 10, 49);
   1129     }
   1130 
   1131     return FALSE;
   1132 }
   1133 
   1134 s32 act_hold_decelerating(struct MarioState *m) {
   1135     s32 val0C;
   1136     s16 slopeClass = mario_get_floor_class(m);
   1137 
   1138     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
   1139         return drop_and_set_mario_action(m, ACT_WALKING, 0);
   1140     }
   1141 
   1142     if (should_begin_sliding(m)) {
   1143         return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0);
   1144     }
   1145 
   1146     if (m->input & INPUT_B_PRESSED) {
   1147         return set_mario_action(m, ACT_THROWING, 0);
   1148     }
   1149 
   1150     if (m->input & INPUT_A_PRESSED) {
   1151         return set_jumping_action(m, ACT_HOLD_JUMP, 0);
   1152     }
   1153 
   1154     if (m->input & INPUT_Z_PRESSED) {
   1155         return drop_and_set_mario_action(m, ACT_CROUCH_SLIDE, 0);
   1156     }
   1157 
   1158     if (m->input & INPUT_NONZERO_ANALOG) {
   1159         return set_mario_action(m, ACT_HOLD_WALKING, 0);
   1160     }
   1161 
   1162     if (update_decelerating_speed(m)) {
   1163         return set_mario_action(m, ACT_HOLD_IDLE, 0);
   1164     }
   1165 
   1166     m->intendedMag *= 0.4f;
   1167 
   1168     switch (perform_ground_step(m)) {
   1169         case GROUND_STEP_LEFT_GROUND:
   1170             set_mario_action(m, ACT_HOLD_FREEFALL, 0);
   1171             break;
   1172 
   1173         case GROUND_STEP_HIT_WALL:
   1174             if (slopeClass == SURFACE_CLASS_VERY_SLIPPERY) {
   1175                 mario_bonk_reflection(m, TRUE);
   1176             } else {
   1177                 mario_set_forward_vel(m, 0.0f);
   1178             }
   1179             break;
   1180     }
   1181 
   1182     if (slopeClass == SURFACE_CLASS_VERY_SLIPPERY) {
   1183         set_mario_animation(m, MARIO_ANIM_IDLE_WITH_LIGHT_OBJ);
   1184         play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
   1185         adjust_sound_for_speed(m);
   1186         m->particleFlags |= PARTICLE_DUST;
   1187     } else {
   1188         //! (Speed Crash) This crashes if Mario has more speed than 2^15 speed.
   1189         if ((val0C = (s32)(m->forwardVel * 0x10000)) < 0x1000) {
   1190             val0C = 0x1000;
   1191         }
   1192 
   1193         set_mario_anim_with_accel(m, MARIO_ANIM_WALK_WITH_LIGHT_OBJ, val0C);
   1194         play_step_sound(m, 12, 62);
   1195     }
   1196 
   1197     return FALSE;
   1198 }
   1199 
   1200 s32 act_riding_shell_ground(struct MarioState *m) {
   1201     s16 startYaw = m->faceAngle[1];
   1202 
   1203     if (m->input & INPUT_A_PRESSED) {
   1204         return set_mario_action(m, ACT_RIDING_SHELL_JUMP, 0);
   1205     }
   1206 
   1207     if (m->input & INPUT_Z_PRESSED) {
   1208         mario_stop_riding_object(m);
   1209         if (m->forwardVel < 24.0f) {
   1210             mario_set_forward_vel(m, 24.0f);
   1211         }
   1212         return set_mario_action(m, ACT_CROUCH_SLIDE, 0);
   1213     }
   1214 
   1215     update_shell_speed(m);
   1216     set_mario_animation(m, m->actionArg == 0 ? MARIO_ANIM_START_RIDING_SHELL : MARIO_ANIM_RIDING_SHELL);
   1217 
   1218     switch (perform_ground_step(m)) {
   1219         case GROUND_STEP_LEFT_GROUND:
   1220             set_mario_action(m, ACT_RIDING_SHELL_FALL, 0);
   1221             break;
   1222 
   1223         case GROUND_STEP_HIT_WALL:
   1224             mario_stop_riding_object(m);
   1225             play_sound(m->flags & MARIO_METAL_CAP ? SOUND_ACTION_METAL_BONK : SOUND_ACTION_BONK,
   1226                        m->marioObj->header.gfx.cameraToObject);
   1227             m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1228             set_mario_action(m, ACT_BACKWARD_GROUND_KB, 0);
   1229             break;
   1230     }
   1231 
   1232     tilt_body_ground_shell(m, startYaw);
   1233     if (m->floor->type == SURFACE_BURNING) {
   1234         play_sound(SOUND_MOVING_RIDING_SHELL_LAVA, m->marioObj->header.gfx.cameraToObject);
   1235     } else {
   1236         play_sound(SOUND_MOVING_TERRAIN_RIDING_SHELL + m->terrainSoundAddend,
   1237                    m->marioObj->header.gfx.cameraToObject);
   1238     }
   1239 
   1240     adjust_sound_for_speed(m);
   1241 #if ENABLE_RUMBLE
   1242     reset_rumble_timers();
   1243 #endif
   1244     return FALSE;
   1245 }
   1246 
   1247 s32 act_crawling(struct MarioState *m) {
   1248     s32 val04;
   1249 
   1250     if (should_begin_sliding(m)) {
   1251         return set_mario_action(m, ACT_BEGIN_SLIDING, 0);
   1252     }
   1253 
   1254     if (m->input & INPUT_FIRST_PERSON) {
   1255         return set_mario_action(m, ACT_STOP_CRAWLING, 0);
   1256     }
   1257 
   1258     if (m->input & INPUT_A_PRESSED) {
   1259         return set_jumping_action(m, ACT_JUMP, 0);
   1260     }
   1261 
   1262     if (check_ground_dive_or_punch(m)) {
   1263         return TRUE;
   1264     }
   1265 
   1266     if (m->input & INPUT_UNKNOWN_5) {
   1267         return set_mario_action(m, ACT_STOP_CRAWLING, 0);
   1268     }
   1269 
   1270     if (!(m->input & INPUT_Z_DOWN)) {
   1271         return set_mario_action(m, ACT_STOP_CRAWLING, 0);
   1272     }
   1273 
   1274     m->intendedMag *= 0.1f;
   1275 
   1276     update_walking_speed(m);
   1277 
   1278     switch (perform_ground_step(m)) {
   1279         case GROUND_STEP_LEFT_GROUND:
   1280             set_mario_action(m, ACT_FREEFALL, 0);
   1281             break;
   1282 
   1283         case GROUND_STEP_HIT_WALL:
   1284             if (m->forwardVel > 10.0f) {
   1285                 mario_set_forward_vel(m, 10.0f);
   1286             }
   1287             //! Possibly unintended missing break
   1288 
   1289         case GROUND_STEP_NONE:
   1290             align_with_floor(m);
   1291             break;
   1292     }
   1293 
   1294     val04 = (s32)(m->intendedMag * 2.0f * 0x10000);
   1295     set_mario_anim_with_accel(m, MARIO_ANIM_CRAWLING, val04);
   1296     play_step_sound(m, 26, 79);
   1297     return FALSE;
   1298 }
   1299 
   1300 s32 act_burning_ground(struct MarioState *m) {
   1301     if (m->input & INPUT_A_PRESSED) {
   1302         return set_mario_action(m, ACT_BURNING_JUMP, 0);
   1303     }
   1304 
   1305     m->marioObj->oMarioBurnTimer += 2;
   1306     if (m->marioObj->oMarioBurnTimer > 160) {
   1307         return set_mario_action(m, ACT_WALKING, 0);
   1308     }
   1309 
   1310     if (m->waterLevel - m->floorHeight > 50.0f) {
   1311         play_sound(SOUND_GENERAL_FLAME_OUT, m->marioObj->header.gfx.cameraToObject);
   1312         return set_mario_action(m, ACT_WALKING, 0);
   1313     }
   1314 
   1315     if (m->forwardVel < 8.0f) {
   1316         m->forwardVel = 8.0f;
   1317     }
   1318     if (m->forwardVel > 48.0f) {
   1319         m->forwardVel = 48.0f;
   1320     }
   1321 
   1322     m->forwardVel = approach_f32(m->forwardVel, 32.0f, 4.0f, 1.0f);
   1323 
   1324     if (m->input & INPUT_NONZERO_ANALOG) {
   1325         m->faceAngle[1] =
   1326             m->intendedYaw - approach_s32((s16)(m->intendedYaw - m->faceAngle[1]), 0, 0x600, 0x600);
   1327     }
   1328 
   1329     apply_slope_accel(m);
   1330 
   1331     if (perform_ground_step(m) == GROUND_STEP_LEFT_GROUND) {
   1332         set_mario_action(m, ACT_BURNING_FALL, 0);
   1333     }
   1334 
   1335     set_mario_anim_with_accel(m, MARIO_ANIM_RUNNING, (s32)(m->forwardVel / 2.0f * 0x10000));
   1336     play_step_sound(m, 9, 45);
   1337 
   1338     m->particleFlags |= PARTICLE_FIRE;
   1339     play_sound(SOUND_MOVING_LAVA_BURN, m->marioObj->header.gfx.cameraToObject);
   1340 
   1341     m->health -= 10;
   1342     if (m->health < 0x100) {
   1343         set_mario_action(m, ACT_STANDING_DEATH, 0);
   1344     }
   1345 
   1346     m->marioBodyState->eyeState = MARIO_EYES_DEAD;
   1347 #if ENABLE_RUMBLE
   1348     reset_rumble_timers();
   1349 #endif
   1350     return FALSE;
   1351 }
   1352 
   1353 void tilt_body_butt_slide(struct MarioState *m) {
   1354     s16 intendedDYaw = m->intendedYaw - m->faceAngle[1];
   1355     m->marioBodyState->torsoAngle[0] = (s32)(5461.3335f * m->intendedMag / 32.0f * coss(intendedDYaw));
   1356     m->marioBodyState->torsoAngle[2] = (s32)(-(5461.3335f * m->intendedMag / 32.0f * sins(intendedDYaw)));
   1357 }
   1358 
   1359 void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32 animation) {
   1360     Vec3f pos;
   1361 
   1362     vec3f_copy(pos, m->pos);
   1363     play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
   1364 
   1365 #if ENABLE_RUMBLE
   1366     reset_rumble_timers();
   1367 #endif
   1368 
   1369     adjust_sound_for_speed(m);
   1370 
   1371     switch (perform_ground_step(m)) {
   1372         case GROUND_STEP_LEFT_GROUND:
   1373             set_mario_action(m, airAction, 0);
   1374             if (m->forwardVel < -50.0f || 50.0f < m->forwardVel) {
   1375                 play_sound(SOUND_MARIO_HOOHOO, m->marioObj->header.gfx.cameraToObject);
   1376             }
   1377             break;
   1378 
   1379         case GROUND_STEP_NONE:
   1380             set_mario_animation(m, animation);
   1381             align_with_floor(m);
   1382             m->particleFlags |= PARTICLE_DUST;
   1383             break;
   1384 
   1385         case GROUND_STEP_HIT_WALL:
   1386             if (!mario_floor_is_slippery(m)) {
   1387 #ifdef VERSION_JP
   1388                 m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1389 #else
   1390                 if (m->forwardVel > 16.0f) {
   1391                     m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1392                 }
   1393 #endif
   1394                 slide_bonk(m, ACT_GROUND_BONK, endAction);
   1395             } else if (m->wall != NULL) {
   1396                 s16 wallAngle = atan2s(m->wall->normal.z, m->wall->normal.x);
   1397                 f32 slideSpeed = sqrtf(m->slideVelX * m->slideVelX + m->slideVelZ * m->slideVelZ);
   1398 
   1399                 if ((slideSpeed *= 0.9) < 4.0f) {
   1400                     slideSpeed = 4.0f;
   1401                 }
   1402 
   1403                 m->slideYaw = wallAngle - (s16)(m->slideYaw - wallAngle) + 0x8000;
   1404 
   1405                 m->vel[0] = m->slideVelX = slideSpeed * sins(m->slideYaw);
   1406                 m->vel[2] = m->slideVelZ = slideSpeed * coss(m->slideYaw);
   1407             }
   1408 
   1409             align_with_floor(m);
   1410             break;
   1411     }
   1412 }
   1413 
   1414 s32 common_slide_action_with_jump(struct MarioState *m, u32 stopAction, u32 jumpAction, u32 airAction,
   1415                                   s32 animation) {
   1416     if (m->actionTimer == 5) {
   1417         if (m->input & INPUT_A_PRESSED) {
   1418             return set_jumping_action(m, jumpAction, 0);
   1419         }
   1420     } else {
   1421         m->actionTimer++;
   1422     }
   1423 
   1424     if (update_sliding(m, 4.0f)) {
   1425         return set_mario_action(m, stopAction, 0);
   1426     }
   1427 
   1428     common_slide_action(m, stopAction, airAction, animation);
   1429     return FALSE;
   1430 }
   1431 
   1432 s32 act_butt_slide(struct MarioState *m) {
   1433     s32 cancel = common_slide_action_with_jump(m, ACT_BUTT_SLIDE_STOP, ACT_JUMP, ACT_BUTT_SLIDE_AIR,
   1434                                                MARIO_ANIM_SLIDE);
   1435     tilt_body_butt_slide(m);
   1436     return cancel;
   1437 }
   1438 
   1439 s32 act_hold_butt_slide(struct MarioState *m) {
   1440     s32 cancel;
   1441 
   1442     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
   1443         return drop_and_set_mario_action(m, ACT_BUTT_SLIDE, 0);
   1444     }
   1445 
   1446     cancel = common_slide_action_with_jump(m, ACT_HOLD_BUTT_SLIDE_STOP, ACT_HOLD_JUMP, ACT_HOLD_BUTT_SLIDE_AIR,
   1447                                            MARIO_ANIM_SLIDING_ON_BOTTOM_WITH_LIGHT_OBJ);
   1448     tilt_body_butt_slide(m);
   1449     return cancel;
   1450 }
   1451 
   1452 s32 act_crouch_slide(struct MarioState *m) {
   1453     s32 cancel;
   1454 
   1455     if (m->input & INPUT_ABOVE_SLIDE) {
   1456         return set_mario_action(m, ACT_BUTT_SLIDE, 0);
   1457     }
   1458 
   1459     if (m->actionTimer < 30) {
   1460         m->actionTimer++;
   1461         if (m->input & INPUT_A_PRESSED) {
   1462             if (m->forwardVel > 10.0f) {
   1463                 return set_jumping_action(m, ACT_LONG_JUMP, 0);
   1464             }
   1465         }
   1466     }
   1467 
   1468     if (m->input & INPUT_B_PRESSED) {
   1469         if (m->forwardVel >= 10.0f) {
   1470             return set_mario_action(m, ACT_SLIDE_KICK, 0);
   1471         } else {
   1472             return set_mario_action(m, ACT_MOVE_PUNCHING, 0x0009);
   1473         }
   1474     }
   1475 
   1476     if (m->input & INPUT_A_PRESSED) {
   1477         return set_jumping_action(m, ACT_JUMP, 0);
   1478     }
   1479 
   1480     if (m->input & INPUT_FIRST_PERSON) {
   1481         return set_mario_action(m, ACT_BRAKING, 0);
   1482     }
   1483 
   1484     cancel = common_slide_action_with_jump(m, ACT_CROUCHING, ACT_JUMP, ACT_FREEFALL,
   1485                                            MARIO_ANIM_START_CROUCHING);
   1486     return cancel;
   1487 }
   1488 
   1489 s32 act_slide_kick_slide(struct MarioState *m) {
   1490     if (m->input & INPUT_A_PRESSED) {
   1491 #if ENABLE_RUMBLE
   1492         queue_rumble_data(5, 80);
   1493 #endif
   1494         return set_jumping_action(m, ACT_FORWARD_ROLLOUT, 0);
   1495     }
   1496 
   1497     set_mario_animation(m, MARIO_ANIM_SLIDE_KICK);
   1498     if (is_anim_at_end(m) && m->forwardVel < 1.0f) {
   1499         return set_mario_action(m, ACT_SLIDE_KICK_SLIDE_STOP, 0);
   1500     }
   1501 
   1502     update_sliding(m, 1.0f);
   1503     switch (perform_ground_step(m)) {
   1504         case GROUND_STEP_LEFT_GROUND:
   1505             set_mario_action(m, ACT_FREEFALL, 2);
   1506             break;
   1507 
   1508         case GROUND_STEP_HIT_WALL:
   1509             mario_bonk_reflection(m, TRUE);
   1510             m->particleFlags |= PARTICLE_VERTICAL_STAR;
   1511             set_mario_action(m, ACT_BACKWARD_GROUND_KB, 0);
   1512             break;
   1513     }
   1514 
   1515     play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject);
   1516     m->particleFlags |= PARTICLE_DUST;
   1517     return FALSE;
   1518 }
   1519 
   1520 s32 stomach_slide_action(struct MarioState *m, u32 stopAction, u32 airAction, s32 animation) {
   1521     if (m->actionTimer == 5) {
   1522         if (!(m->input & INPUT_ABOVE_SLIDE) && (m->input & (INPUT_A_PRESSED | INPUT_B_PRESSED))) {
   1523 #if ENABLE_RUMBLE
   1524             queue_rumble_data(5, 80);
   1525 #endif
   1526             return drop_and_set_mario_action(
   1527                 m, m->forwardVel >= 0.0f ? ACT_FORWARD_ROLLOUT : ACT_BACKWARD_ROLLOUT, 0);
   1528         }
   1529     } else {
   1530         m->actionTimer++;
   1531     }
   1532 
   1533     if (update_sliding(m, 4.0f)) {
   1534         return set_mario_action(m, stopAction, 0);
   1535     }
   1536 
   1537     common_slide_action(m, stopAction, airAction, animation);
   1538     return FALSE;
   1539 }
   1540 
   1541 s32 act_stomach_slide(struct MarioState *m) {
   1542     s32 cancel = stomach_slide_action(m, ACT_STOMACH_SLIDE_STOP, ACT_FREEFALL, MARIO_ANIM_SLIDE_DIVE);
   1543     return cancel;
   1544 }
   1545 
   1546 s32 act_hold_stomach_slide(struct MarioState *m) {
   1547     s32 cancel;
   1548 
   1549     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
   1550         return drop_and_set_mario_action(m, ACT_STOMACH_SLIDE, 0);
   1551     }
   1552 
   1553     cancel = stomach_slide_action(m, ACT_DIVE_PICKING_UP, ACT_HOLD_FREEFALL, MARIO_ANIM_SLIDE_DIVE);
   1554     return cancel;
   1555 }
   1556 
   1557 s32 act_dive_slide(struct MarioState *m) {
   1558     if (!(m->input & INPUT_ABOVE_SLIDE) && (m->input & (INPUT_A_PRESSED | INPUT_B_PRESSED))) {
   1559 #if ENABLE_RUMBLE
   1560         queue_rumble_data(5, 80);
   1561 #endif
   1562         return set_mario_action(m, m->forwardVel > 0.0f ? ACT_FORWARD_ROLLOUT : ACT_BACKWARD_ROLLOUT,
   1563                                 0);
   1564     }
   1565 
   1566     play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
   1567 
   1568     //! If the dive slide ends on the same frame that we pick up on object,
   1569     // Mario will not be in the dive slide action for the call to
   1570     // mario_check_object_grab, and so will end up in the regular picking action,
   1571     // rather than the picking up after dive action.
   1572 
   1573     if (update_sliding(m, 8.0f) && is_anim_at_end(m)) {
   1574         mario_set_forward_vel(m, 0.0f);
   1575         set_mario_action(m, ACT_STOMACH_SLIDE_STOP, 0);
   1576     }
   1577 
   1578     if (mario_check_object_grab(m)) {
   1579         mario_grab_used_object(m);
   1580         m->marioBodyState->grabPos = GRAB_POS_LIGHT_OBJ;
   1581         return TRUE;
   1582     }
   1583 
   1584     common_slide_action(m, ACT_STOMACH_SLIDE_STOP, ACT_FREEFALL, MARIO_ANIM_DIVE);
   1585     return FALSE;
   1586 }
   1587 
   1588 s32 common_ground_knockback_action(struct MarioState *m, s32 animation, s32 arg2, s32 arg3, s32 arg4) {
   1589     s32 animFrame;
   1590 
   1591     if (arg3) {
   1592         play_mario_heavy_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
   1593     }
   1594 
   1595     if (arg4 > 0) {
   1596         play_sound_if_no_flag(m, SOUND_MARIO_ATTACKED, MARIO_MARIO_SOUND_PLAYED);
   1597     } else {
   1598 #ifdef VERSION_JP
   1599         play_sound_if_no_flag(m, SOUND_MARIO_OOOF, MARIO_MARIO_SOUND_PLAYED);
   1600 #else
   1601         play_sound_if_no_flag(m, SOUND_MARIO_OOOF2, MARIO_MARIO_SOUND_PLAYED);
   1602 #endif
   1603     }
   1604 
   1605     if (m->forwardVel > 32.0f) {
   1606         m->forwardVel = 32.0f;
   1607     }
   1608     if (m->forwardVel < -32.0f) {
   1609         m->forwardVel = -32.0f;
   1610     }
   1611 
   1612     animFrame = set_mario_animation(m, animation);
   1613     if (animFrame < arg2) {
   1614         apply_landing_accel(m, 0.9f);
   1615     } else if (m->forwardVel >= 0.0f) {
   1616         mario_set_forward_vel(m, 0.1f);
   1617     } else {
   1618         mario_set_forward_vel(m, -0.1f);
   1619     }
   1620 
   1621     if (perform_ground_step(m) == GROUND_STEP_LEFT_GROUND) {
   1622         if (m->forwardVel >= 0.0f) {
   1623             set_mario_action(m, ACT_FORWARD_AIR_KB, arg4);
   1624         } else {
   1625             set_mario_action(m, ACT_BACKWARD_AIR_KB, arg4);
   1626         }
   1627     } else if (is_anim_at_end(m)) {
   1628         if (m->health < 0x100) {
   1629             set_mario_action(m, ACT_STANDING_DEATH, 0);
   1630         } else {
   1631             if (arg4 > 0) {
   1632                 m->invincTimer = 30;
   1633             }
   1634             set_mario_action(m, ACT_IDLE, 0);
   1635         }
   1636     }
   1637 
   1638     return animFrame;
   1639 }
   1640 
   1641 s32 act_hard_backward_ground_kb(struct MarioState *m) {
   1642     s32 animFrame =
   1643         common_ground_knockback_action(m, MARIO_ANIM_FALL_OVER_BACKWARDS, 43, TRUE, m->actionArg);
   1644     if (animFrame == 43 && m->health < 0x100) {
   1645         set_mario_action(m, ACT_DEATH_ON_BACK, 0);
   1646     }
   1647 
   1648 #ifndef VERSION_JP
   1649     if (animFrame == 54 && m->prevAction == ACT_SPECIAL_DEATH_EXIT) {
   1650         play_sound(SOUND_MARIO_MAMA_MIA, m->marioObj->header.gfx.cameraToObject);
   1651     }
   1652 #endif
   1653 
   1654     if (animFrame == 69) {
   1655         play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING);
   1656     }
   1657 
   1658     return FALSE;
   1659 }
   1660 
   1661 s32 act_hard_forward_ground_kb(struct MarioState *m) {
   1662     s32 animFrame =
   1663         common_ground_knockback_action(m, MARIO_ANIM_LAND_ON_STOMACH, 21, TRUE, m->actionArg);
   1664     if (animFrame == 23 && m->health < 0x100) {
   1665         set_mario_action(m, ACT_DEATH_ON_STOMACH, 0);
   1666     }
   1667 
   1668     return FALSE;
   1669 }
   1670 
   1671 s32 act_backward_ground_kb(struct MarioState *m) {
   1672     common_ground_knockback_action(m, MARIO_ANIM_BACKWARD_KB, 22, TRUE, m->actionArg);
   1673     return FALSE;
   1674 }
   1675 
   1676 s32 act_forward_ground_kb(struct MarioState *m) {
   1677     common_ground_knockback_action(m, MARIO_ANIM_FORWARD_KB, 20, TRUE, m->actionArg);
   1678     return FALSE;
   1679 }
   1680 
   1681 s32 act_soft_backward_ground_kb(struct MarioState *m) {
   1682     common_ground_knockback_action(m, MARIO_ANIM_SOFT_BACK_KB, 100, FALSE, m->actionArg);
   1683     return FALSE;
   1684 }
   1685 
   1686 s32 act_soft_forward_ground_kb(struct MarioState *m) {
   1687     common_ground_knockback_action(m, MARIO_ANIM_SOFT_FRONT_KB, 100, FALSE, m->actionArg);
   1688     return FALSE;
   1689 }
   1690 
   1691 s32 act_ground_bonk(struct MarioState *m) {
   1692     s32 animFrame =
   1693         common_ground_knockback_action(m, MARIO_ANIM_GROUND_BONK, 32, TRUE, m->actionArg);
   1694     if (animFrame == 32) {
   1695         play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
   1696     }
   1697     return FALSE;
   1698 }
   1699 
   1700 s32 act_death_exit_land(struct MarioState *m) {
   1701     s32 animFrame;
   1702 
   1703     apply_landing_accel(m, 0.9f);
   1704     play_mario_heavy_landing_sound_once(m, SOUND_ACTION_TERRAIN_BODY_HIT_GROUND);
   1705 
   1706     animFrame = set_mario_animation(m, MARIO_ANIM_FALL_OVER_BACKWARDS);
   1707 
   1708     if (animFrame == 54) {
   1709         play_sound(SOUND_MARIO_MAMA_MIA, m->marioObj->header.gfx.cameraToObject);
   1710     }
   1711     if (animFrame == 68) {
   1712         play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
   1713     }
   1714 
   1715     if (is_anim_at_end(m)) {
   1716         set_mario_action(m, ACT_IDLE, 0);
   1717     }
   1718 
   1719     return FALSE;
   1720 }
   1721 
   1722 u32 common_landing_action(struct MarioState *m, s16 animation, u32 airAction) {
   1723     u32 stepResult;
   1724 
   1725     if (m->input & INPUT_NONZERO_ANALOG) {
   1726         apply_landing_accel(m, 0.98f);
   1727     } else if (m->forwardVel >= 16.0f) {
   1728         apply_slope_decel(m, 2.0f);
   1729     } else {
   1730         m->vel[1] = 0.0f;
   1731     }
   1732 
   1733     stepResult = perform_ground_step(m);
   1734     switch (stepResult) {
   1735         case GROUND_STEP_LEFT_GROUND:
   1736             set_mario_action(m, airAction, 0);
   1737             break;
   1738 
   1739         case GROUND_STEP_HIT_WALL:
   1740             set_mario_animation(m, MARIO_ANIM_PUSHING);
   1741             break;
   1742     }
   1743 
   1744     if (m->forwardVel > 16.0f) {
   1745         m->particleFlags |= PARTICLE_DUST;
   1746     }
   1747 
   1748     set_mario_animation(m, animation);
   1749     play_mario_landing_sound_once(m, SOUND_ACTION_TERRAIN_LANDING);
   1750 
   1751     if (m->floor->type >= SURFACE_SHALLOW_QUICKSAND && m->floor->type <= SURFACE_MOVING_QUICKSAND) {
   1752         m->quicksandDepth += (4 - m->actionTimer) * 3.5f - 0.5f;
   1753     }
   1754 
   1755     return stepResult;
   1756 }
   1757 
   1758 s32 common_landing_cancels(struct MarioState *m, struct LandingAction *landingAction,
   1759                            s32 (*setAPressAction)(struct MarioState *, u32, u32)) {
   1760     //! Everything here, including floor steepness, is checked before checking
   1761     // if Mario is actually on the floor. This leads to e.g. remote sliding.
   1762 
   1763     if (m->floor->normal.y < 0.2923717f) {
   1764         return mario_push_off_steep_floor(m, landingAction->verySteepAction, 0);
   1765     }
   1766 
   1767     m->doubleJumpTimer = landingAction->unk02;
   1768 
   1769     if (should_begin_sliding(m)) {
   1770         return set_mario_action(m, landingAction->slideAction, 0);
   1771     }
   1772 
   1773     if (m->input & INPUT_FIRST_PERSON) {
   1774         return set_mario_action(m, landingAction->endAction, 0);
   1775     }
   1776 
   1777     if (++m->actionTimer >= landingAction->numFrames) {
   1778         return set_mario_action(m, landingAction->endAction, 0);
   1779     }
   1780 
   1781     if (m->input & INPUT_A_PRESSED) {
   1782         return setAPressAction(m, landingAction->aPressedAction, 0);
   1783     }
   1784 
   1785     if (m->input & INPUT_OFF_FLOOR) {
   1786         return set_mario_action(m, landingAction->offFloorAction, 0);
   1787     }
   1788 
   1789     return FALSE;
   1790 }
   1791 
   1792 s32 act_jump_land(struct MarioState *m) {
   1793     if (common_landing_cancels(m, &sJumpLandAction, set_jumping_action)) {
   1794         return TRUE;
   1795     }
   1796 
   1797     common_landing_action(m, MARIO_ANIM_LAND_FROM_SINGLE_JUMP, ACT_FREEFALL);
   1798     return FALSE;
   1799 }
   1800 
   1801 s32 act_freefall_land(struct MarioState *m) {
   1802     if (common_landing_cancels(m, &sFreefallLandAction, set_jumping_action)) {
   1803         return TRUE;
   1804     }
   1805 
   1806     common_landing_action(m, MARIO_ANIM_GENERAL_LAND, ACT_FREEFALL);
   1807     return FALSE;
   1808 }
   1809 
   1810 s32 act_side_flip_land(struct MarioState *m) {
   1811     if (common_landing_cancels(m, &sSideFlipLandAction, set_jumping_action)) {
   1812         return TRUE;
   1813     }
   1814 
   1815     if (common_landing_action(m, MARIO_ANIM_SLIDEFLIP_LAND, ACT_FREEFALL) != GROUND_STEP_HIT_WALL) {
   1816         m->marioObj->header.gfx.angle[1] += 0x8000;
   1817     }
   1818     return FALSE;
   1819 }
   1820 
   1821 s32 act_hold_jump_land(struct MarioState *m) {
   1822     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
   1823         return drop_and_set_mario_action(m, ACT_JUMP_LAND_STOP, 0);
   1824     }
   1825 
   1826     if (common_landing_cancels(m, &sHoldJumpLandAction, set_jumping_action)) {
   1827         return TRUE;
   1828     }
   1829 
   1830     common_landing_action(m, MARIO_ANIM_JUMP_LAND_WITH_LIGHT_OBJ, ACT_HOLD_FREEFALL);
   1831     return FALSE;
   1832 }
   1833 
   1834 s32 act_hold_freefall_land(struct MarioState *m) {
   1835     if (m->marioObj->oInteractStatus & INT_STATUS_MARIO_DROP_OBJECT) {
   1836         return drop_and_set_mario_action(m, ACT_FREEFALL_LAND_STOP, 0);
   1837     }
   1838 
   1839     if (common_landing_cancels(m, &sHoldFreefallLandAction, set_jumping_action)) {
   1840         return TRUE;
   1841     }
   1842 
   1843     common_landing_action(m, MARIO_ANIM_FALL_LAND_WITH_LIGHT_OBJ, ACT_HOLD_FREEFALL);
   1844     return FALSE;
   1845 }
   1846 
   1847 s32 act_long_jump_land(struct MarioState *m) {
   1848 #if defined(VERSION_SH) || defined(VERSION_CN)
   1849     // BLJ (Backwards Long Jump) speed build up fix, crushing SimpleFlips's dreams since July 1997
   1850     if (m->forwardVel < 0.0f) {
   1851         m->forwardVel = 0.0f;
   1852     }
   1853 #endif
   1854 
   1855     if (!(m->input & INPUT_Z_DOWN)) {
   1856         m->input &= ~INPUT_A_PRESSED;
   1857     }
   1858 
   1859     if (common_landing_cancels(m, &sLongJumpLandAction, set_jumping_action)) {
   1860         return TRUE;
   1861     }
   1862 
   1863     if (!(m->input & INPUT_NONZERO_ANALOG)) {
   1864         play_sound_if_no_flag(m, SOUND_MARIO_UH2_2, MARIO_MARIO_SOUND_PLAYED);
   1865     }
   1866 
   1867     common_landing_action(m,
   1868                           !m->marioObj->oMarioLongJumpIsSlow ? MARIO_ANIM_CROUCH_FROM_FAST_LONGJUMP
   1869                                                              : MARIO_ANIM_CROUCH_FROM_SLOW_LONGJUMP,
   1870                           ACT_FREEFALL);
   1871     return FALSE;
   1872 }
   1873 
   1874 s32 act_double_jump_land(struct MarioState *m) {
   1875     if (common_landing_cancels(m, &sDoubleJumpLandAction, set_triple_jump_action)) {
   1876         return TRUE;
   1877     }
   1878     common_landing_action(m, MARIO_ANIM_LAND_FROM_DOUBLE_JUMP, ACT_FREEFALL);
   1879     return FALSE;
   1880 }
   1881 
   1882 s32 act_triple_jump_land(struct MarioState *m) {
   1883     m->input &= ~INPUT_A_PRESSED;
   1884 
   1885     if (common_landing_cancels(m, &sTripleJumpLandAction, set_jumping_action)) {
   1886         return TRUE;
   1887     }
   1888 
   1889     if (!(m->input & INPUT_NONZERO_ANALOG)) {
   1890         play_sound_if_no_flag(m, SOUND_MARIO_HAHA, MARIO_MARIO_SOUND_PLAYED);
   1891     }
   1892 
   1893     common_landing_action(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_FREEFALL);
   1894     return FALSE;
   1895 }
   1896 
   1897 s32 act_backflip_land(struct MarioState *m) {
   1898     if (!(m->input & INPUT_Z_DOWN)) {
   1899         m->input &= ~INPUT_A_PRESSED;
   1900     }
   1901 
   1902     if (common_landing_cancels(m, &sBackflipLandAction, set_jumping_action)) {
   1903         return TRUE;
   1904     }
   1905 
   1906     if (!(m->input & INPUT_NONZERO_ANALOG)) {
   1907         play_sound_if_no_flag(m, SOUND_MARIO_HAHA, MARIO_MARIO_SOUND_PLAYED);
   1908     }
   1909 
   1910     common_landing_action(m, MARIO_ANIM_TRIPLE_JUMP_LAND, ACT_FREEFALL);
   1911     return FALSE;
   1912 }
   1913 
   1914 s32 quicksand_jump_land_action(struct MarioState *m, s32 animation1, s32 animation2, u32 endAction,
   1915                                u32 airAction) {
   1916     if (m->actionTimer++ < 6) {
   1917         m->quicksandDepth -= (7 - m->actionTimer) * 0.8f;
   1918         if (m->quicksandDepth < 1.0f) {
   1919             m->quicksandDepth = 1.1f;
   1920         }
   1921 
   1922         play_mario_jump_sound(m);
   1923         set_mario_animation(m, animation1);
   1924     } else {
   1925         if (m->actionTimer >= 13) {
   1926             return set_mario_action(m, endAction, 0);
   1927         }
   1928 
   1929         set_mario_animation(m, animation2);
   1930     }
   1931 
   1932     apply_landing_accel(m, 0.95f);
   1933     if (perform_ground_step(m) == GROUND_STEP_LEFT_GROUND) {
   1934         set_mario_action(m, airAction, 0);
   1935     }
   1936 
   1937     return FALSE;
   1938 }
   1939 
   1940 s32 act_quicksand_jump_land(struct MarioState *m) {
   1941     s32 cancel = quicksand_jump_land_action(m, MARIO_ANIM_SINGLE_JUMP, MARIO_ANIM_LAND_FROM_SINGLE_JUMP,
   1942                                             ACT_JUMP_LAND_STOP, ACT_FREEFALL);
   1943     return cancel;
   1944 }
   1945 
   1946 s32 act_hold_quicksand_jump_land(struct MarioState *m) {
   1947     s32 cancel = quicksand_jump_land_action(m, MARIO_ANIM_JUMP_WITH_LIGHT_OBJ,
   1948                                             MARIO_ANIM_JUMP_LAND_WITH_LIGHT_OBJ, ACT_HOLD_JUMP_LAND_STOP,
   1949                                             ACT_HOLD_FREEFALL);
   1950     return cancel;
   1951 }
   1952 
   1953 s32 check_common_moving_cancels(struct MarioState *m) {
   1954     if (m->pos[1] < m->waterLevel - 100) {
   1955         return set_water_plunge_action(m);
   1956     }
   1957 
   1958     if (!(m->action & ACT_FLAG_INVULNERABLE) && (m->input & INPUT_STOMPED)) {
   1959         return drop_and_set_mario_action(m, ACT_SHOCKWAVE_BOUNCE, 0);
   1960     }
   1961 
   1962     if (m->input & INPUT_SQUISHED) {
   1963         return drop_and_set_mario_action(m, ACT_SQUISHED, 0);
   1964     }
   1965 
   1966     if (!(m->action & ACT_FLAG_INVULNERABLE)) {
   1967         if (m->health < 0x100) {
   1968             return drop_and_set_mario_action(m, ACT_STANDING_DEATH, 0);
   1969         }
   1970     }
   1971 
   1972     return FALSE;
   1973 }
   1974 
   1975 s32 mario_execute_moving_action(struct MarioState *m) {
   1976     s32 cancel;
   1977 
   1978     if (check_common_moving_cancels(m)) {
   1979         return TRUE;
   1980     }
   1981 
   1982     if (mario_update_quicksand(m, 0.25f)) {
   1983         return TRUE;
   1984     }
   1985 
   1986     /* clang-format off */
   1987     switch (m->action) {
   1988         case ACT_WALKING:                  cancel = act_walking(m);                  break;
   1989         case ACT_HOLD_WALKING:             cancel = act_hold_walking(m);             break;
   1990         case ACT_HOLD_HEAVY_WALKING:       cancel = act_hold_heavy_walking(m);       break;
   1991         case ACT_TURNING_AROUND:           cancel = act_turning_around(m);           break;
   1992         case ACT_FINISH_TURNING_AROUND:    cancel = act_finish_turning_around(m);    break;
   1993         case ACT_BRAKING:                  cancel = act_braking(m);                  break;
   1994         case ACT_RIDING_SHELL_GROUND:      cancel = act_riding_shell_ground(m);      break;
   1995         case ACT_CRAWLING:                 cancel = act_crawling(m);                 break;
   1996         case ACT_BURNING_GROUND:           cancel = act_burning_ground(m);           break;
   1997         case ACT_DECELERATING:             cancel = act_decelerating(m);             break;
   1998         case ACT_HOLD_DECELERATING:        cancel = act_hold_decelerating(m);        break;
   1999         case ACT_BUTT_SLIDE:               cancel = act_butt_slide(m);               break;
   2000         case ACT_STOMACH_SLIDE:            cancel = act_stomach_slide(m);            break;
   2001         case ACT_HOLD_BUTT_SLIDE:          cancel = act_hold_butt_slide(m);          break;
   2002         case ACT_HOLD_STOMACH_SLIDE:       cancel = act_hold_stomach_slide(m);       break;
   2003         case ACT_DIVE_SLIDE:               cancel = act_dive_slide(m);               break;
   2004         case ACT_MOVE_PUNCHING:            cancel = act_move_punching(m);            break;
   2005         case ACT_CROUCH_SLIDE:             cancel = act_crouch_slide(m);             break;
   2006         case ACT_SLIDE_KICK_SLIDE:         cancel = act_slide_kick_slide(m);         break;
   2007         case ACT_HARD_BACKWARD_GROUND_KB:  cancel = act_hard_backward_ground_kb(m);  break;
   2008         case ACT_HARD_FORWARD_GROUND_KB:   cancel = act_hard_forward_ground_kb(m);   break;
   2009         case ACT_BACKWARD_GROUND_KB:       cancel = act_backward_ground_kb(m);       break;
   2010         case ACT_FORWARD_GROUND_KB:        cancel = act_forward_ground_kb(m);        break;
   2011         case ACT_SOFT_BACKWARD_GROUND_KB:  cancel = act_soft_backward_ground_kb(m);  break;
   2012         case ACT_SOFT_FORWARD_GROUND_KB:   cancel = act_soft_forward_ground_kb(m);   break;
   2013         case ACT_GROUND_BONK:              cancel = act_ground_bonk(m);              break;
   2014         case ACT_DEATH_EXIT_LAND:          cancel = act_death_exit_land(m);          break;
   2015         case ACT_JUMP_LAND:                cancel = act_jump_land(m);                break;
   2016         case ACT_FREEFALL_LAND:            cancel = act_freefall_land(m);            break;
   2017         case ACT_DOUBLE_JUMP_LAND:         cancel = act_double_jump_land(m);         break;
   2018         case ACT_SIDE_FLIP_LAND:           cancel = act_side_flip_land(m);           break;
   2019         case ACT_HOLD_JUMP_LAND:           cancel = act_hold_jump_land(m);           break;
   2020         case ACT_HOLD_FREEFALL_LAND:       cancel = act_hold_freefall_land(m);       break;
   2021         case ACT_TRIPLE_JUMP_LAND:         cancel = act_triple_jump_land(m);         break;
   2022         case ACT_BACKFLIP_LAND:            cancel = act_backflip_land(m);            break;
   2023         case ACT_QUICKSAND_JUMP_LAND:      cancel = act_quicksand_jump_land(m);      break;
   2024         case ACT_HOLD_QUICKSAND_JUMP_LAND: cancel = act_hold_quicksand_jump_land(m); break;
   2025         case ACT_LONG_JUMP_LAND:           cancel = act_long_jump_land(m);           break;
   2026     }
   2027     /* clang-format on */
   2028 
   2029     if (!cancel && (m->input & INPUT_IN_WATER)) {
   2030         m->particleFlags |= PARTICLE_WAVE_TRAIL;
   2031         m->particleFlags &= ~PARTICLE_DUST;
   2032     }
   2033 
   2034     return cancel;
   2035 }