From e71ba07b22074e437b52a43b9be00a36a9cc2eaa Mon Sep 17 00:00:00 2001 From: Arceveti <73617174+Arceveti@users.noreply.github.com> Date: Mon, 27 Sep 2021 10:21:25 -0700 Subject: [PATCH] Add some fields to MarioState --- include/object_constants.h | 1 + include/types.h | 22 ++- src/game/mario.c | 294 ++++++++++++----------------- src/game/mario.h | 6 +- src/game/mario_actions_automatic.c | 11 +- src/game/mario_actions_moving.c | 10 +- src/game/mario_actions_submerged.c | 9 +- src/game/mario_step.c | 47 ++--- src/game/object_list_processor.c | 2 +- src/game/rendering_graph_node.c | 3 +- 10 files changed, 168 insertions(+), 237 deletions(-) diff --git a/include/object_constants.h b/include/object_constants.h index fdc789e4..c95c6eb2 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -97,6 +97,7 @@ OBJ_MOVE_UNDERWATER_ON_GROUND) /* oActiveParticleFlags */ +#define ACTIVE_PARTICLE_NONE (0 << 0) // 0x00000000 #define ACTIVE_PARTICLE_DUST (1 << 0) // 0x00000001 #define ACTIVE_PARTICLE_UNUSED_1 (1 << 1) // 0x00000002 #define ACTIVE_PARTICLE_UNUSED_2 (1 << 2) // 0x00000004 diff --git a/include/types.h b/include/types.h index 4037586a..5d22ebeb 100644 --- a/include/types.h +++ b/include/types.h @@ -348,7 +348,7 @@ struct MarioState /*0x68*/ struct Surface *floor; /*0x6C*/ f32 ceilHeight; /*0x70*/ f32 floorHeight; - /*0x74*/ s16 floorAngle; + /*0x74*/ s16 floorYaw; /*0x76*/ s16 waterLevel; /*0x78*/ struct Object *interactObj; /*0x7C*/ struct Object *heldObj; @@ -364,14 +364,14 @@ struct MarioState /*0xA4*/ u32 collidedObjInteractTypes; /*0xA8*/ s16 numCoins; /*0xAA*/ s16 numStars; - /*0xAC*/ s8 numKeys; // Unused key mechanic - /*0xAD*/ s8 numLives; + /*0xAC*/ s8 numKeys; // Unused key mechanic + /*0xAD*/ s8 numLives; /*0xAE*/ s16 health; /*0xB0*/ s16 animYTrans; - /*0xB2*/ u8 hurtCounter; - /*0xB3*/ u8 healCounter; - /*0xB4*/ u8 squishTimer; - /*0xB5*/ u8 fadeWarpOpacity; + /*0xB2*/ u8 hurtCounter; + /*0xB3*/ u8 healCounter; + /*0xB4*/ u8 squishTimer; + /*0xB5*/ u8 fadeWarpOpacity; /*0xB6*/ u16 capTimer; /*0xB8*/ s16 prevNumStarsForDialog; /*0xBC*/ f32 peakHeight; @@ -381,6 +381,14 @@ struct MarioState s16 breath; u8 breathCounter; #endif + Vec3f lastSafePos; + Vec3f prevPos; + f32 lateralSpeed; + f32 moveSpeed; + Angle movePitch; + Angle moveYaw; + Angle ceilYaw; + Angle wallYaw; }; #endif // TYPES_H diff --git a/src/game/mario.c b/src/game/mario.c index 73711bf4..2d6f7474 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -178,8 +178,7 @@ s32 is_anim_past_frame(struct MarioState *m, s16 animFrame) { * and returns the animation's flags. */ s16 find_mario_anim_flags_and_translation(struct Object *obj, s32 yaw, Vec3s translation) { - f32 dx; - f32 dz; + f32 dx, dz; struct Animation *curAnim = (void *) obj->header.gfx.animInfo.curAnim; s16 animFrame = geo_update_animation_frame(&obj->header.gfx.animInfo, NULL); @@ -193,7 +192,7 @@ s16 find_mario_anim_flags_and_translation(struct Object *obj, s32 yaw, Vec3s tra translation[1] = *(animValues + (retrieve_animation_index(animFrame, &animIndex))) / 4.0f; dz = *(animValues + (retrieve_animation_index(animFrame, &animIndex))) / 4.0f; - translation[0] = (dx * c) + (dz * s); + translation[0] = ( dx * c) + (dz * s); translation[2] = (-dx * s) + (dz * c); return curAnim->flags; @@ -524,9 +523,7 @@ s32 mario_facing_downhill(struct MarioState *m, s32 turnYaw) { if (turnYaw && m->forwardVel < 0.0f) { faceAngleYaw += 0x8000; } - - faceAngleYaw = m->floorAngle - faceAngleYaw; - + faceAngleYaw = m->floorYaw - faceAngleYaw; return (-0x4000 < faceAngleYaw) && (faceAngleYaw < 0x4000); } @@ -536,28 +533,15 @@ s32 mario_facing_downhill(struct MarioState *m, s32 turnYaw) { u32 mario_floor_is_slippery(struct MarioState *m) { f32 normY; - if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE - && m->floor->normal.y < 0.9998477f //~cos(1 deg) - ) { + if ((m->area->terrainType & TERRAIN_MASK) == TERRAIN_SLIDE && m->floor->normal.y < 0.9998477f) { //~cos(1 deg) return TRUE; } switch (mario_get_floor_class(m)) { - case SURFACE_VERY_SLIPPERY: - normY = 0.9848077f; //~cos(10 deg) - break; - - case SURFACE_SLIPPERY: - normY = 0.9396926f; //~cos(20 deg) - break; - - default: - normY = 0.7880108f; //~cos(38 deg) - break; - - case SURFACE_NOT_SLIPPERY: - normY = 0.0f; - break; + case SURFACE_VERY_SLIPPERY: normY = 0.9848077f; break; //~cos(10 deg) + case SURFACE_SLIPPERY: normY = 0.9396926f; break; //~cos(20 deg) + default: normY = 0.7880108f; break; //~cos(38 deg) + case SURFACE_NOT_SLIPPERY: normY = 0.0f; break; } return m->floor->normal.y <= normY; @@ -575,21 +559,10 @@ s32 mario_floor_is_slope(struct MarioState *m) { } switch (mario_get_floor_class(m)) { - case SURFACE_VERY_SLIPPERY: - normY = 0.9961947f; // ~cos(5 deg) - break; - - case SURFACE_SLIPPERY: - normY = 0.9848077f; // ~cos(10 deg) - break; - - default: - normY = 0.9659258f; // ~cos(15 deg) - break; - - case SURFACE_NOT_SLIPPERY: - normY = 0.9396926f; // ~cos(20 deg) - break; + case SURFACE_VERY_SLIPPERY: normY = 0.9961947f; break; // ~cos(5 deg) + case SURFACE_SLIPPERY: normY = 0.9848077f; break; // ~cos(10 deg) + default: normY = 0.9659258f; break; // ~cos(15 deg) + case SURFACE_NOT_SLIPPERY: normY = 0.9396926f; break; // ~cos(20 deg) } return m->floor->normal.y <= normY; @@ -613,21 +586,10 @@ s32 mario_floor_is_steep(struct MarioState *m) { // This does not matter in vanilla game practice. if (!mario_facing_downhill(m, FALSE)) { switch (mario_get_floor_class(m)) { - case SURFACE_VERY_SLIPPERY: - normY = 0.9659258f; // ~cos(15 deg) - break; - - case SURFACE_SLIPPERY: - normY = 0.9396926f; // ~cos(20 deg) - break; - - default: - normY = 0.8660254f; // ~cos(30 deg) - break; - - case SURFACE_NOT_SLIPPERY: - normY = 0.8660254f; // ~cos(30 deg) - break; + case SURFACE_VERY_SLIPPERY: normY = 0.9659258f; break; // ~cos(15 deg) + case SURFACE_SLIPPERY: normY = 0.9396926f; break; // ~cos(20 deg) + default: normY = 0.8660254f; break; // ~cos(30 deg) + case SURFACE_NOT_SLIPPERY: normY = 0.8660254f; break; // ~cos(30 deg) } result = m->floor->normal.y <= normY; @@ -641,14 +603,11 @@ s32 mario_floor_is_steep(struct MarioState *m) { */ f32 find_floor_height_relative_polar(struct MarioState *m, s16 angleFromMario, f32 distFromMario) { struct Surface *floor; - f32 floorY; f32 y = sins(m->faceAngle[1] + angleFromMario) * distFromMario; f32 x = coss(m->faceAngle[1] + angleFromMario) * distFromMario; - floorY = find_floor(m->pos[0] + y, m->pos[1] + 100.0f, m->pos[2] + x, &floor); - - return floorY; + return find_floor(m->pos[0] + y, m->pos[1] + 100.0f, m->pos[2] + x, &floor); } /** @@ -668,19 +627,21 @@ s16 find_floor_slope(struct MarioState *m, s16 yawOffset) { backwardFloorY = get_surface_height_at_location((m->pos[0] - x), (m->pos[2] - z), floor); } else { forwardFloorY = find_floor((m->pos[0] + x), (m->pos[1] + 100.0f), (m->pos[2] + z), &floor); + if (floor == NULL) forwardFloorY = m->floorHeight; // handle OOB slopes backwardFloorY = find_floor((m->pos[0] - x), (m->pos[1] + 100.0f), (m->pos[2] - z), &floor); + if (floor == NULL) backwardFloorY = m->floorHeight; // handle OOB slopes } #else forwardFloorY = find_floor((m->pos[0] + x), (m->pos[1] + 100.0f), (m->pos[2] + z), &floor); + if (floor == NULL) forwardFloorY = m->floorHeight; // handle OOB slopes backwardFloorY = find_floor((m->pos[0] - x), (m->pos[1] + 100.0f), (m->pos[2] - z), &floor); + if (floor == NULL) backwardFloorY = m->floorHeight; // handle OOB slopes #endif - //! If Mario is near OOB, these floorY's can sometimes be -11000. - // This will cause these to be off and give improper slopes. forwardYDelta = forwardFloorY - m->pos[1]; backwardYDelta = m->pos[1] - backwardFloorY; - if (forwardYDelta * forwardYDelta < backwardYDelta * backwardYDelta) { + if (sqr(forwardYDelta) < sqr(backwardYDelta)) { result = atan2s(5.0f, forwardYDelta); } else { result = atan2s(5.0f, backwardYDelta); @@ -689,6 +650,32 @@ s16 find_floor_slope(struct MarioState *m, s16 yawOffset) { return result; } +Bool32 set_mario_wall(struct MarioState *m, struct Surface *wall) { + if (m->wall != wall) { + m->wall = wall; + if (m->wall != NULL) m->wallYaw = SURFACE_YAW(wall); + } + return (m->wall != NULL); +} + +Bool32 set_mario_ceil(struct MarioState *m, struct Surface *ceil, f32 ceilHeight) { + if (m->ceil != ceil) { + m->ceil = ceil; + if (m->ceil != NULL) m->ceilYaw = SURFACE_YAW(ceil); + } + m->ceilHeight = ceilHeight; + return (m->ceil != NULL); +} + +Bool32 set_mario_floor(struct MarioState *m, struct Surface *floor, f32 floorHeight) { + if (m->floor != floor) { + m->floor = floor; + if (m->floor != NULL) m->floorYaw = SURFACE_YAW(floor); + } + m->floorHeight = floorHeight; + return (m->floor != NULL); +} + /** * Adjusts Mario's camera and sound based on his action status. */ @@ -720,8 +707,8 @@ void set_steep_jump_action(struct MarioState *m) { if (m->forwardVel > 0.0f) { //! ((s16)0x8000) has undefined behavior. Therefore, this downcast has - // undefined behavior if m->floorAngle >= 0. - s16 angleTemp = m->floorAngle + 0x8000; + // undefined behavior if m->floorYaw >= 0. + s16 angleTemp = m->floorYaw + 0x8000; s16 faceAngleTemp = m->faceAngle[1] - angleTemp; f32 y = sins(faceAngleTemp) * m->forwardVel; @@ -955,21 +942,10 @@ static u32 set_mario_action_cutscene(struct MarioState *m, u32 action, UNUSED u3 */ u32 set_mario_action(struct MarioState *m, u32 action, u32 actionArg) { switch (action & ACT_GROUP_MASK) { - case ACT_GROUP_MOVING: - action = set_mario_action_moving(m, action, actionArg); - break; - - case ACT_GROUP_AIRBORNE: - action = set_mario_action_airborne(m, action, actionArg); - break; - - case ACT_GROUP_SUBMERGED: - action = set_mario_action_submerged(m, action, actionArg); - break; - - case ACT_GROUP_CUTSCENE: - action = set_mario_action_cutscene(m, action, actionArg); - break; + case ACT_GROUP_MOVING: action = set_mario_action_moving (m, action, actionArg); break; + case ACT_GROUP_AIRBORNE: action = set_mario_action_airborne (m, action, actionArg); break; + case ACT_GROUP_SUBMERGED: action = set_mario_action_submerged(m, action, actionArg); break; + case ACT_GROUP_CUTSCENE: action = set_mario_action_cutscene (m, action, actionArg); break; } // Resets the sound played flags, meaning Mario can play those sound types again. @@ -1111,19 +1087,10 @@ s32 check_common_action_exits(struct MarioState *m) { * object holding actions. A holding variant of the above function. */ s32 check_common_hold_action_exits(struct MarioState *m) { - if (m->input & INPUT_A_PRESSED) { - return set_mario_action(m, ACT_HOLD_JUMP, 0); - } - if (m->input & INPUT_OFF_FLOOR) { - return set_mario_action(m, ACT_HOLD_FREEFALL, 0); - } - if (m->input & INPUT_NONZERO_ANALOG) { - return set_mario_action(m, ACT_HOLD_WALKING, 0); - } - if (m->input & INPUT_ABOVE_SLIDE) { - return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0); - } - + if (m->input & INPUT_A_PRESSED ) return set_mario_action(m, ACT_HOLD_JUMP, 0); + if (m->input & INPUT_OFF_FLOOR ) return set_mario_action(m, ACT_HOLD_FREEFALL, 0); + if (m->input & INPUT_NONZERO_ANALOG) return set_mario_action(m, ACT_HOLD_WALKING, 0); + if (m->input & INPUT_ABOVE_SLIDE ) return set_mario_action(m, ACT_HOLD_BEGIN_SLIDING, 0); return FALSE; } @@ -1149,7 +1116,7 @@ s32 transition_submerged_to_walking(struct MarioState *m) { s32 transition_submerged_to_airborne(struct MarioState *m) { set_camera_mode(m->area->camera, m->area->camera->defMode, 1); - vec3s_set(m->angleVel, 0, 0, 0); + vec3_zero(m->angleVel); if (m->heldObj == NULL) { if (m->input & INPUT_A_DOWN) return set_mario_action(m, ACT_DIVE, 0); @@ -1173,7 +1140,7 @@ s32 set_water_plunge_action(struct MarioState *m) { m->faceAngle[2] = 0; - vec3s_set(m->angleVel, 0, 0, 0); + vec3_zero(m->angleVel); if (!(m->action & ACT_FLAG_DIVING)) { m->faceAngle[0] = 0; @@ -1307,6 +1274,11 @@ void update_mario_joystick_inputs(struct MarioState *m) { } } +Bool32 analog_stick_held_back(struct MarioState *m) { + s16 intendedDYaw = (m->intendedYaw - m->faceAngle[1]); + return ((intendedDYaw < -0x471C) || (intendedDYaw > 0x471C)); +} + /** * Resolves wall collisions, and updates a variety of inputs. */ @@ -1333,7 +1305,7 @@ void update_mario_geometry_inputs(struct MarioState *m) { m->waterLevel = find_water_level(m->pos[0], m->pos[2]); if (m->floor != NULL) { - m->floorAngle = atan2s(m->floor->normal.z, m->floor->normal.x); + m->floorYaw = atan2s(m->floor->normal.z, m->floor->normal.x); m->terrainSoundAddend = mario_get_terrain_sound_addend(m); if ((m->pos[1] > m->waterLevel - 40) && mario_floor_is_slippery(m)) { @@ -1375,13 +1347,12 @@ void update_mario_inputs(struct MarioState *m) { m->collidedObjInteractTypes = m->marioObj->collidedObjInteractTypes; m->flags &= 0xFFFFFF; - #ifdef PUPPYCAM - if (gPuppyCam.mode3Flags & PUPPYCAM_MODE3_ENTER_FIRST_PERSON || (gPuppyCam.flags & PUPPYCAM_BEHAVIOUR_FREE && gPuppyCam.debugFlags & PUPPYDEBUG_LOCK_CONTROLS)) - { +#ifdef PUPPYCAM + if (gPuppyCam.mode3Flags & PUPPYCAM_MODE3_ENTER_FIRST_PERSON || (gPuppyCam.flags & PUPPYCAM_BEHAVIOUR_FREE && gPuppyCam.debugFlags & PUPPYDEBUG_LOCK_CONTROLS)) { m->input = INPUT_FIRST_PERSON; return; } - #endif +#endif update_mario_button_inputs(m); update_mario_joystick_inputs(m); @@ -1460,7 +1431,6 @@ void set_submerged_cam_preset_and_spawn_bubbles(struct MarioState *m) { */ void update_mario_health(struct MarioState *m) { s32 terrainIsSnow; - if (m->health >= 0x100) { // When already healing or hurting Mario, Mario's HP is not changed any more here. if (((u32) m->healCounter | (u32) m->hurtCounter) == 0) { @@ -1497,12 +1467,8 @@ void update_mario_health(struct MarioState *m) { m->hurtCounter--; } - if (m->health > 0x880) { - m->health = 0x880; - } - if (m->health < 0x100) { - m->health = 0xFF; - } + if (m->health > 0x880) m->health = 0x880; + if (m->health < 0x100) m->health = 0xFF; #ifndef BREATH_METER // Play a noise to alert the player when Mario is close to drowning. if (((m->action & ACT_GROUP_MASK) == ACT_GROUP_SUBMERGED) && (m->health < 0x300)) { @@ -1548,6 +1514,7 @@ void update_mario_breath(struct MarioState *m) { } if (m->breath > 0x880) m->breath = 0x880; if (m->breath < 0x100) { + // If breath is "zero", set health to "zero" m->breath = 0xFF; m->health = 0xFF; } @@ -1598,13 +1565,12 @@ void sink_mario_in_quicksand(struct MarioState *m) { } /** - * Is a binary representation of the frames to flicker Mario's cap when the timer - * is running out. - * + * Is a binary representation of the frames to flicker Mario's cap when the timer is running out. + * 0x4444449249255555 * Equals [1000]^5 . [100]^8 . [10]^9 . [1] in binary, which is * 100010001000100010001001001001001001001001001010101010101010101. */ -u64 sCapFlickerFrames = 0x4444449249255555; +u64 sCapFlickerFrames = 0b100010001000100010001001001001001001001001001010101010101010101; /** * Updates the cap flags mainly based on the cap timer. @@ -1739,97 +1705,79 @@ void queue_rumble_particles(void) { #endif /** - * Main function for executing Mario's behavior. + * Main function for executing Mario's behavior. Returns particleFlags. */ -s32 execute_mario_action(UNUSED struct Object *o) { +s32 execute_mario_action(struct MarioState *m) { s32 inLoop = TRUE; - - if (gMarioState->action) { - gMarioState->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; - mario_reset_bodystate(gMarioState); - update_mario_inputs(gMarioState); + // Updates once per frame: + vec3f_get_dist_and_lateral_dist_and_angle(m->prevPos, m->pos, &m->moveSpeed, &m->lateralSpeed, &m->movePitch, &m->moveYaw); + vec3_copy(m->prevPos, m->pos); + if (m->action) { + m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE; + mario_reset_bodystate(m); + update_mario_inputs(m); #ifdef PUPPYCAM if (!(gPuppyCam.flags & PUPPYCAM_BEHAVIOUR_FREE)) #endif - mario_handle_special_floors(gMarioState); - mario_process_interactions(gMarioState); + mario_handle_special_floors(m); + mario_process_interactions(m); // If Mario is OOB, stop executing actions. - if (gMarioState->floor == NULL) { - return 0; + if (m->floor == NULL) { + return ACTIVE_PARTICLE_NONE; } // The function can loop through many action shifts in one frame, // which can lead to unexpected sub-frame behavior. Could potentially hang // if a loop of actions were found, but there has not been a situation found. while (inLoop) { - switch (gMarioState->action & ACT_GROUP_MASK) { - case ACT_GROUP_STATIONARY: - inLoop = mario_execute_stationary_action(gMarioState); - break; - - case ACT_GROUP_MOVING: - inLoop = mario_execute_moving_action(gMarioState); - break; - - case ACT_GROUP_AIRBORNE: - inLoop = mario_execute_airborne_action(gMarioState); - break; - - case ACT_GROUP_SUBMERGED: - inLoop = mario_execute_submerged_action(gMarioState); - break; - - case ACT_GROUP_CUTSCENE: - inLoop = mario_execute_cutscene_action(gMarioState); - break; - - case ACT_GROUP_AUTOMATIC: - inLoop = mario_execute_automatic_action(gMarioState); - break; - - case ACT_GROUP_OBJECT: - inLoop = mario_execute_object_action(gMarioState); - break; + switch (m->action & ACT_GROUP_MASK) { + case ACT_GROUP_STATIONARY: inLoop = mario_execute_stationary_action(m); break; + case ACT_GROUP_MOVING: inLoop = mario_execute_moving_action (m); break; + case ACT_GROUP_AIRBORNE: inLoop = mario_execute_airborne_action (m); break; + case ACT_GROUP_SUBMERGED: inLoop = mario_execute_submerged_action (m); break; + case ACT_GROUP_CUTSCENE: inLoop = mario_execute_cutscene_action (m); break; + case ACT_GROUP_AUTOMATIC: inLoop = mario_execute_automatic_action (m); break; + case ACT_GROUP_OBJECT: inLoop = mario_execute_object_action (m); break; } } - sink_mario_in_quicksand(gMarioState); - squish_mario_model(gMarioState); - set_submerged_cam_preset_and_spawn_bubbles(gMarioState); - update_mario_health(gMarioState); + sink_mario_in_quicksand(m); + squish_mario_model(m); + set_submerged_cam_preset_and_spawn_bubbles(m); + update_mario_health(m); #ifdef BREATH_METER - update_mario_breath(gMarioState); + update_mario_breath(m); #endif - update_mario_info_for_cam(gMarioState); - mario_update_hitbox_and_cap_model(gMarioState); + update_mario_info_for_cam(m); + mario_update_hitbox_and_cap_model(m); // Both of the wind handling portions play wind audio only in // non-Japanese releases. - if (gMarioState->floor->type == SURFACE_HORIZONTAL_WIND) { - spawn_wind_particles(0, (gMarioState->floor->force << 8)); + if (m->floor->type == SURFACE_HORIZONTAL_WIND) { + spawn_wind_particles(0, (m->floor->force << 8)); #ifndef VERSION_JP - play_sound(SOUND_ENV_WIND2, gMarioState->marioObj->header.gfx.cameraToObject); + play_sound(SOUND_ENV_WIND2, m->marioObj->header.gfx.cameraToObject); #endif } - if (gMarioState->floor->type == SURFACE_VERTICAL_WIND) { + if (m->floor->type == SURFACE_VERTICAL_WIND) { spawn_wind_particles(1, 0); #ifndef VERSION_JP - play_sound(SOUND_ENV_WIND2, gMarioState->marioObj->header.gfx.cameraToObject); + play_sound(SOUND_ENV_WIND2, m->marioObj->header.gfx.cameraToObject); #endif } play_infinite_stairs_music(); - gMarioState->marioObj->oInteractStatus = 0; + m->marioObj->oInteractStatus = 0; #if ENABLE_RUMBLE queue_rumble_particles(); #endif - return gMarioState->particleFlags; + return m->particleFlags; } - return 0; + return ACTIVE_PARTICLE_NONE; } /************************************************** @@ -1873,6 +1821,7 @@ void init_mario(void) { vec3_copy(gMarioState->faceAngle, gMarioSpawnInfo->startAngle); vec3_zero(gMarioState->angleVel); vec3_copy(gMarioState->pos, gMarioSpawnInfo->startPos); + vec3_copy(gMarioState->prevPos, gMarioState->pos); vec3_zero(gMarioState->vel); gMarioState->floorHeight = find_floor(gMarioState->pos[0], gMarioState->pos[1], gMarioState->pos[2], &gMarioState->floor); @@ -1882,33 +1831,22 @@ void init_mario(void) { gMarioState->marioObj->header.gfx.pos[1] = gMarioState->pos[1]; - gMarioState->action = - (gMarioState->pos[1] <= (gMarioState->waterLevel - 100)) ? ACT_WATER_IDLE : ACT_IDLE; + gMarioState->action = (gMarioState->pos[1] <= (gMarioState->waterLevel - 100)) ? ACT_WATER_IDLE : ACT_IDLE; mario_reset_bodystate(gMarioState); update_mario_info_for_cam(gMarioState); gMarioState->marioBodyState->punchState = 0; - gMarioState->marioObj->oPosX = gMarioState->pos[0]; - gMarioState->marioObj->oPosY = gMarioState->pos[1]; - gMarioState->marioObj->oPosZ = gMarioState->pos[2]; - - gMarioState->marioObj->oMoveAnglePitch = gMarioState->faceAngle[0]; - gMarioState->marioObj->oMoveAngleYaw = gMarioState->faceAngle[1]; - gMarioState->marioObj->oMoveAngleRoll = gMarioState->faceAngle[2]; + vec3_copy(&gMarioState->marioObj->oPosVec, gMarioState->pos); + vec3_copy(&gMarioState->marioObj->oMoveAngleVec, gMarioState->faceAngle); vec3f_copy(gMarioState->marioObj->header.gfx.pos, gMarioState->pos); vec3s_set(gMarioState->marioObj->header.gfx.angle, 0, gMarioState->faceAngle[1], 0); if (save_file_get_cap_pos(capPos)) { capObject = spawn_object(gMarioState->marioObj, MODEL_MARIOS_CAP, bhvNormalCap); - - capObject->oPosX = capPos[0]; - capObject->oPosY = capPos[1]; - capObject->oPosZ = capPos[2]; - + vec3_copy(&capObject->oPosVec, capPos); capObject->oForwardVel = 0; - capObject->oMoveAngleYaw = 0; } } diff --git a/src/game/mario.h b/src/game/mario.h index b991b7e6..ae547b89 100644 --- a/src/game/mario.h +++ b/src/game/mario.h @@ -34,6 +34,10 @@ s32 mario_floor_is_slope(struct MarioState *m); s32 mario_floor_is_steep(struct MarioState *m); f32 find_floor_height_relative_polar(struct MarioState *m, s16 angleFromMario, f32 distFromMario); s16 find_floor_slope(struct MarioState *m, s16 yawOffset); +Bool32 set_mario_wall(struct MarioState *m, struct Surface *wall); +Bool32 set_mario_ceil(struct MarioState *m, struct Surface *ceil, f32 ceilHeight); +Bool32 set_mario_floor(struct MarioState *m, struct Surface *floor, f32 floorHeight); +Bool32 analog_stick_held_back(struct MarioState *m); void update_mario_sound_and_camera(struct MarioState *m); void set_steep_jump_action(struct MarioState *m); u32 set_mario_action(struct MarioState *m, u32 action, u32 actionArg); @@ -46,7 +50,7 @@ s32 check_common_hold_action_exits(struct MarioState *m); s32 transition_submerged_to_walking(struct MarioState *m); s32 transition_submerged_to_airborne(struct MarioState *m); s32 set_water_plunge_action(struct MarioState *m); -s32 execute_mario_action(UNUSED struct Object *o); +s32 execute_mario_action(struct MarioState *m); void init_mario(void); void init_mario_from_save_file(void); diff --git a/src/game/mario_actions_automatic.c b/src/game/mario_actions_automatic.c index 2baa0912..0e75239d 100644 --- a/src/game/mario_actions_automatic.c +++ b/src/game/mario_actions_automatic.c @@ -290,7 +290,7 @@ s32 perform_hanging_step(struct MarioState *m, Vec3f nextPos) { struct WallCollisionData wallCollisionData; resolve_and_return_wall_collisions(nextPos, 50.0f, 50.0f, &wallCollisionData); - m->wall = wallCollisionData.numWalls == 0 ? NULL : wallCollisionData.walls[0]; + set_mario_wall(m, wallCollisionData.numWalls == 0 ? NULL : wallCollisionData.walls[0]); floorHeight = find_floor(nextPos[0], nextPos[1], nextPos[2], &floor); ceilHeight = find_ceil(nextPos[0], nextPos[1] + 3.0f, nextPos[2], &ceil); @@ -319,10 +319,8 @@ s32 perform_hanging_step(struct MarioState *m, Vec3f nextPos) { nextPos[1] = m->ceilHeight - 160.0f; vec3f_copy(m->pos, nextPos); - m->floor = floor; - m->floorHeight = floorHeight; - m->ceil = ceil; - m->ceilHeight = ceilHeight; + set_mario_floor(m, floor, floorHeight); + set_mario_ceil(m, ceil, ceilHeight); return HANG_NONE; } @@ -830,8 +828,7 @@ s32 act_tornado_twirling(struct MarioState *m) { floorHeight = find_floor(nextPos[0], nextPos[1], nextPos[2], &floor); if (floor != NULL) { - m->floor = floor; - m->floorHeight = floorHeight; + set_mario_floor(m, floor, floorHeight); vec3f_copy(m->pos, nextPos); } else { if (nextPos[1] >= m->floorHeight) { diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index fbad6e02..8f7fcf45 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -291,7 +291,7 @@ void apply_slope_accel(struct MarioState *m) { struct Surface *floor = m->floor; f32 steepness = sqrtf(sqr(floor->normal.x) + sqr(floor->normal.z)); - s16 floorDYaw = m->floorAngle - m->faceAngle[1]; + s16 floorDYaw = m->floorYaw - m->faceAngle[1]; if (mario_floor_is_slope(m)) { s16 slopeClass = 0; @@ -356,8 +356,7 @@ void update_shell_speed(struct MarioState *m) { f32 targetSpeed; if (m->floorHeight < m->waterLevel) { - m->floorHeight = m->waterLevel; - m->floor = &gWaterSurfacePseudoFloor; + set_mario_floor(m, &gWaterSurfacePseudoFloor, m->waterLevel); m->floor->originOffset = m->waterLevel; //! Negative origin offset } @@ -434,11 +433,6 @@ s32 update_decelerating_speed(struct MarioState *m) { return stopped; } -s32 analog_stick_held_back(struct MarioState *m) { - s16 intendedDYaw = (m->intendedYaw - m->faceAngle[1]); - return ((intendedDYaw < -0x471C) || (intendedDYaw > 0x471C)); -} - void update_walking_speed(struct MarioState *m) { f32 maxTargetSpeed; diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index d1bc44e1..d0a15374 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -87,8 +87,7 @@ static u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos) { if (nextPos[1] >= floorHeight) { if (ceilHeight - nextPos[1] >= 160.0f) { vec3f_copy(m->pos, nextPos); - m->floor = floor; - m->floorHeight = floorHeight; + set_mario_floor(m, floor, floorHeight); if (wall != NULL) { return WATER_STEP_HIT_WALL; @@ -103,8 +102,7 @@ static u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos) { //! Water ceiling downwarp vec3f_set(m->pos, nextPos[0], ceilHeight - 160.0f, nextPos[2]); - m->floor = floor; - m->floorHeight = floorHeight; + set_mario_floor(m, floor, floorHeight); return WATER_STEP_HIT_CEILING; } else { if (ceilHeight - floorHeight < 160.0f) { @@ -112,8 +110,7 @@ static u32 perform_water_full_step(struct MarioState *m, Vec3f nextPos) { } vec3f_set(m->pos, nextPos[0], floorHeight, nextPos[2]); - m->floor = floor; - m->floorHeight = floorHeight; + set_mario_floor(m, floor, floorHeight); return WATER_STEP_HIT_FLOOR; } } diff --git a/src/game/mario_step.c b/src/game/mario_step.c index 7be63e66..c3ddeb9b 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -159,14 +159,14 @@ u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) { } u32 mario_push_off_steep_floor(struct MarioState *m, u32 action, u32 actionArg) { - s16 floorDYaw = m->floorAngle - m->faceAngle[1]; + s16 floorDYaw = m->floorYaw - m->faceAngle[1]; if (floorDYaw > -0x4000 && floorDYaw < 0x4000) { m->forwardVel = 16.0f; - m->faceAngle[1] = m->floorAngle; + m->faceAngle[1] = m->floorYaw; } else { m->forwardVel = -16.0f; - m->faceAngle[1] = m->floorAngle + 0x8000; + m->faceAngle[1] = m->floorYaw + 0x8000; } return set_mario_action(m, action, actionArg); @@ -296,8 +296,7 @@ static s32 perform_ground_quarter_step(struct MarioState *m, Vec3f nextPos) { } vec3f_copy(m->pos, nextPos); - m->floor = floor; - m->floorHeight = floorHeight; + set_mario_floor(m, floor, floorHeight); return GROUND_STEP_LEFT_GROUND; } @@ -306,8 +305,8 @@ static s32 perform_ground_quarter_step(struct MarioState *m, Vec3f nextPos) { } vec3f_set(m->pos, nextPos[0], floorHeight, nextPos[2]); - m->floor = floor; - m->floorHeight = floorHeight; + if (!SURFACE_IS_QUICKSAND(floor->type) && (floor->type != SURFACE_BURNING)) vec3_copy(m->lastSafePos, m->pos); + set_mario_floor(m, floor, floorHeight); if (m->wall != NULL) { oldWallDYaw = atan2s(m->wall->normal.z, m->wall->normal.x) - m->faceAngle[1]; @@ -320,7 +319,7 @@ static s32 perform_ground_quarter_step(struct MarioState *m, Vec3f nextPos) { absWallDYaw = wallDYaw < 0 ? -wallDYaw : wallDYaw; if (absWallDYaw > oldWallDYaw) { oldWallDYaw = absWallDYaw; - m->wall = upperWall.walls[i]; + set_mario_wall(m, upperWall.walls[i]); } if (wallDYaw >= 0x2AAA && wallDYaw <= 0x5555) { @@ -417,7 +416,7 @@ s32 bonk_or_hit_lava_wall(struct MarioState *m, struct WallCollisionData *wallDa if (wallData->walls[i] != NULL) { wallDYaw = atan2s(wallData->walls[i]->normal.z, wallData->walls[i]->normal.x) - m->faceAngle[1]; if (wallData->walls[i]->type == SURFACE_BURNING) { - m->wall = wallData->walls[i]; + set_mario_wall(m, wallData->walls[i]); return AIR_STEP_HIT_LAVA_WALL; } @@ -425,7 +424,7 @@ s32 bonk_or_hit_lava_wall(struct MarioState *m, struct WallCollisionData *wallDa absWallDYaw = wallDYaw < 0 ? -wallDYaw : wallDYaw; if (absWallDYaw > oldWallDYaw) { oldWallDYaw = absWallDYaw; - m->wall = wallData->walls[i]; + set_mario_wall(m, wallData->walls[i]); if (wallDYaw < -0x6000 || wallDYaw > 0x6000) { m->flags |= MARIO_AIR_HIT_WALL; @@ -494,8 +493,7 @@ s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepAr if (ceilHeight - floorHeight > 160.0f) { m->pos[0] = nextPos[0]; m->pos[2] = nextPos[2]; - m->floor = floor; - m->floorHeight = floorHeight; + set_mario_floor(m, floor, floorHeight); } //! When ceilHeight - floorHeight <= 160, the step result says that @@ -536,36 +534,31 @@ s32 perform_air_quarter_step(struct MarioState *m, Vec3f intendedPos, u32 stepAr // misalignment, you can activate these conditions in unexpected situations if ((stepArg & AIR_STEP_CHECK_LEDGE_GRAB) && upperWall.numWalls == 0) { - for (i = 0; i < lowerWall.numWalls; i++) - if ((grabbedWall = check_ledge_grab(m, grabbedWall, lowerWall.walls[i], intendedPos, nextPos, ledgePos, &ledgeFloor))) + for (i = 0; i < lowerWall.numWalls; i++) { + if ((grabbedWall = check_ledge_grab(m, grabbedWall, lowerWall.walls[i], intendedPos, nextPos, ledgePos, &ledgeFloor))) { stepResult = AIR_STEP_GRABBED_LEDGE; - if (stepResult == AIR_STEP_GRABBED_LEDGE) - { + } + } + if (stepResult == AIR_STEP_GRABBED_LEDGE) { vec3f_copy(m->pos, ledgePos); - m->floor = ledgeFloor; - m->floorHeight = ledgePos[1]; - - m->floorAngle = atan2s(ledgeFloor->normal.z, ledgeFloor->normal.x); - + set_mario_floor(m, floor, ledgePos[1]); m->faceAngle[0] = 0; m->faceAngle[1] = atan2s(grabbedWall->normal.z, grabbedWall->normal.x) + 0x8000; } else { vec3f_copy(m->pos, nextPos); - m->floor = floor; - m->floorHeight = floorHeight; + set_mario_floor(m, floor, floorHeight); } return stepResult; } vec3f_copy(m->pos, nextPos); - m->floor = floor; - m->floorHeight = floorHeight; + set_mario_floor(m, floor, floorHeight); stepResult = bonk_or_hit_lava_wall(m, &upperWall); - if (stepResult != AIR_STEP_NONE) + if (stepResult != AIR_STEP_NONE) { return stepResult; - + } return bonk_or_hit_lava_wall(m, &lowerWall); } diff --git a/src/game/object_list_processor.c b/src/game/object_list_processor.c index d4cbb6d4..a584b709 100644 --- a/src/game/object_list_processor.c +++ b/src/game/object_list_processor.c @@ -267,7 +267,7 @@ void bhv_mario_update(void) { u32 particleFlags = 0; s32 i; - particleFlags = execute_mario_action(gCurrentObject); + particleFlags = execute_mario_action(gMarioState); gCurrentObject->oMarioParticleFlags = particleFlags; // Mario code updates MarioState's versions of position etc, so we need diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 451da73d..a6ae802d 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -437,8 +437,7 @@ void geo_process_perspective(struct GraphNodePerspective *node) { gWorldScale = 1.0f; } farClip = CLAMP(farClip / gWorldScale, 4096, 61440); - if (farClip / farClipDelta != 1) - { + if (farClip / farClipDelta != 1) { farClipDelta /= farClip; gWorldScale *= farClipDelta; }