diff --git a/include/config.h b/include/config.h index 3371af74..4a3f5849 100644 --- a/include/config.h +++ b/include/config.h @@ -77,7 +77,7 @@ // 1 is similar to vanilla, but prevents Mario from moving in the wrong direction, and allows finer control with the analog stick. // 2 is similar to mode 1, but a bit further from vanilla, and allows instant turnaround if Mario is moving slower than a certain threshold. // 3 is instant turning to the intended direction regardless of speed and angle. -// 4 is an expeimental asymptotic turn. +// 4 is an experimental asymptotic turn. #define GROUND_TURN_MODE 0 // Improved hanging: // - Doesn't require holding down the A button @@ -105,7 +105,7 @@ #define HANGING_FIX // The last frame that will be considered a firsty when wallkicking #define FIRSTY_LAST_FRAME 1 -// The maximum angle the player can wall kick, in degrees. 0..90 +// The maximum angle the player can wall kick, in degrees. 0..90. To allow 45 degree wall kicks, you must supply `46` to allow 45 and under. #define WALL_KICK_DEGREES 45 // Disable BLJs and crush SimpleFlips's dreams //#define DISABLE_BLJ @@ -131,7 +131,7 @@ // Allow for retries on collecting the remaining blue coins from a blue coin switch #define BLUE_COIN_SWITCH_RETRY // Fixes shell cancel -#define SHELL_CANCEL_FIX +//#define SHELL_CANCEL_FIX // The number of chain balls the Chain Chomp has. Vanilla is 5. #define CHAIN_CHOMP_NUM_SEGMENTS 5 // The number of parts Pokey has, including the head. Vanilla is 5, max is 30. diff --git a/src/engine/math_util.c b/src/engine/math_util.c index be4018dd..6fcf1376 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -29,7 +29,7 @@ Vec3i gVec3iZero = { 0, 0, 0 }; Vec3s gVec3sOne = { 1, 1, 1 }; /// From Wiseguy -static inline s32 roundf(f32 in) { +static inline s32 asm_roundf(f32 in) { f32 tmp; s32 out; __asm__("round.w.s %0,%1" : "=f" (tmp) : "f" (in)); @@ -37,14 +37,18 @@ static inline s32 roundf(f32 in) { return out; } -// static inline float absf(float in) { -// f32 out; -// __asm__("abs.s %0,%1" : "=f" (out) : "f" (in)); -// return out; -// } +f32 roundf(f32 x) { + return asm_roundf(x); +} + +static inline float asm_absf(float in) { + f32 out; + __asm__("abs.s %0,%1" : "=f" (out) : "f" (in)); + return out; +} f32 absf(f32 x) { - return ABSF(x); + return asm_absf(x); } /// Returns the lowest of three values. diff --git a/src/engine/math_util.h b/src/engine/math_util.h index 5262fb71..ed8baf98 100644 --- a/src/engine/math_util.h +++ b/src/engine/math_util.h @@ -449,6 +449,7 @@ extern f32 gSineTable[]; } \ } +f32 roundf(f32 x); f32 absf(f32 x); s32 min_3i(s32 a0, s32 a1, s32 a2); f32 min_3f(f32 a0, f32 a1, f32 a2); diff --git a/src/game/behaviors/pokey.inc.c b/src/game/behaviors/pokey.inc.c index 4d6b39c7..150d6feb 100644 --- a/src/game/behaviors/pokey.inc.c +++ b/src/game/behaviors/pokey.inc.c @@ -143,7 +143,7 @@ static void pokey_act_uninitialized(void) { s32 i; s16 partModel; - if (o->oDistanceToMario < 4000.0f) { + if (o->oDistanceToMario < o->oDrawingDistance) { partModel = MODEL_POKEY_HEAD; for (i = 0; i < POKEY_NUM_SEGMENTS; i++) { @@ -177,7 +177,7 @@ static void pokey_act_wander(void) { if (o->oPokeyNumAliveBodyParts == POKEY_PART_BP_HEAD) { obj_mark_for_deletion(o); - } else if (o->oDistanceToMario > 4500.0f) { + } else if (o->oDistanceToMario > (o->oDrawingDistance + 500.0f)) { o->oAction = POKEY_ACT_UNLOAD_PARTS; o->oForwardVel = 0.0f; } else { diff --git a/src/game/camera.c b/src/game/camera.c index 8d6943f9..6a3cf85d 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -896,13 +896,7 @@ void radial_camera_move(struct Camera *c) { // How much the camera's yaw changed s16 yawOffset = calculate_yaw(sMarioCamState->pos, c->pos) - atan2s(areaDistZ, areaDistX); - - if (yawOffset > maxAreaYaw) { - yawOffset = maxAreaYaw; - } - if (yawOffset < minAreaYaw) { - yawOffset = minAreaYaw; - } + yawOffset = CLAMP(yawOffset, minAreaYaw, maxAreaYaw); // Check if Mario stepped on a surface that rotates the camera. For example, when Mario enters the // gate in BoB, the camera turns right to face up the hill path @@ -3874,23 +3868,16 @@ s32 clamp_positions_and_find_yaw(Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f3 /** * The yaw passed here is the yaw of the direction FROM Mario TO Lakitu. * - * wallYaw always has 90 degrees added to it before this is called -- it's parallel to the wall. - * * @return the new yaw from Mario to rotate towards. - * - * @warning this is jank. It actually returns the yaw that will rotate further INTO the wall. So, the - * developers just add 180 degrees to the result. */ s32 calc_avoid_yaw(s16 yawFromMario, s16 wallYaw) { - s16 yawDiff = wallYaw - yawFromMario + DEGREES(90); - - if (yawDiff < 0) { + if (yawFromMario < (s16)(wallYaw + DEGREES(180))) { // Deflect to the right - yawFromMario = wallYaw; + yawFromMario = wallYaw + DEGREES(90); } else { // Note: this favors the left side if the wall is exactly perpendicular to the camera. // Deflect to the left - yawFromMario = wallYaw + DEGREES(180); + yawFromMario = wallYaw - DEGREES(90); } return yawFromMario; } @@ -6118,7 +6105,7 @@ void resolve_geometry_collisions(Vec3f pos) { s32 rotate_camera_around_walls(UNUSED struct Camera *c, Vec3f cPos, s16 *avoidYaw, s16 yawRange) { struct WallCollisionData colData; struct Surface *wall; - s16 wallYaw, horWallNorm; + s16 wallYaw; // The yaw of the vector from Mario to the camera. s16 yawFromMario; s32 status = 0; @@ -6156,10 +6143,9 @@ s32 rotate_camera_around_walls(UNUSED struct Camera *c, Vec3f cPos, s16 *avoidYa status = 1; wall = colData.walls[colData.numWalls - 1]; // wallYaw is parallel to the wall, not perpendicular - wallYaw = atan2s(wall->normal.z, wall->normal.x) + DEGREES(90); - // Calculate the avoid direction. The function returns the opposite direction so add 180 - // degrees. - *avoidYaw = calc_avoid_yaw(yawFromMario, wallYaw) + DEGREES(180); + wallYaw = SURFACE_YAW(wall); + // Calculate the avoid direction. The function returns the opposite direction so add 180 degrees. + *avoidYaw = calc_avoid_yaw(yawFromMario, wallYaw); } } @@ -6172,8 +6158,7 @@ s32 rotate_camera_around_walls(UNUSED struct Camera *c, Vec3f cPos, s16 *avoidYa if (find_wall_collisions(&colData) != 0) { wall = colData.walls[colData.numWalls - 1]; - horWallNorm = atan2s(wall->normal.z, wall->normal.x); - wallYaw = horWallNorm + DEGREES(90); + wallYaw = SURFACE_YAW(wall); // If Mario would be blocked by the surface, then avoid it if ((is_range_behind_surface(sMarioCamState->pos, cPos, wall, yawRange, SURFACE_WALL_MISC) == 0) && (is_behind_surface(sMarioCamState->pos, wall)) @@ -6181,8 +6166,8 @@ s32 rotate_camera_around_walls(UNUSED struct Camera *c, Vec3f cPos, s16 *avoidYa && (!is_surf_within_bounding_box(wall, -1.f, 150.f, -1.f))) { // Calculate the avoid direction. The function returns the opposite direction so add 180 // degrees. - *avoidYaw = calc_avoid_yaw(yawFromMario, wallYaw) + DEGREES(180); - camera_approach_s16_symmetric_bool(avoidYaw, horWallNorm, yawRange); + *avoidYaw = calc_avoid_yaw(yawFromMario, wallYaw); + camera_approach_s16_symmetric_bool(avoidYaw, wallYaw, yawRange); status = 3; step = 8; } diff --git a/src/game/mario_step.c b/src/game/mario_step.c index ef4618e3..2facbcc2 100644 --- a/src/game/mario_step.c +++ b/src/game/mario_step.c @@ -685,15 +685,6 @@ s32 perform_air_step(struct MarioState *m, u32 stepArg) { vec3f_copy(m->marioObj->header.gfx.pos, m->pos); vec3s_set(m->marioObj->header.gfx.angle, 0, m->faceAngle[1], 0); - /*if (stepResult == AIR_STEP_HIT_WALL && m->wall != NULL) { - wallDYaw = abs_angle_diff(atan2s(m->wall->normal.z, m->wall->normal.x), m->faceAngle[1]); - if ((stepArg & AIR_STEP_CHECK_BONK) && (wallDYaw > DEGREES(180 - WALL_KICK_DEGREES))) { - if (m->forwardVel > 16.0f) { - mario_bonk_reflection(m, (stepArg & AIR_STEP_BONK_NEGATE_SPEED), m->wall); - } - } - }*/ - return stepResult; } diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index f755c750..e54bf38b 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -244,15 +244,15 @@ void obj_set_held_state(struct Object *obj, const BehaviorScript *heldBehavior) } f32 lateral_dist_between_objects(struct Object *obj1, struct Object *obj2) { - f32 lateralDist; - vec3f_get_lateral_dist(&obj1->oPosVec, &obj2->oPosVec, &lateralDist); - return lateralDist; + register f32 dx = (obj2->oPosX - obj1->oPosX); + register f32 dz = (obj2->oPosZ - obj1->oPosZ); + return sqrtf(sqr(dx) + sqr(dz)); } f32 dist_between_objects(struct Object *obj1, struct Object *obj2) { - f32 dist; - vec3f_get_dist(&obj1->oPosVec, &obj2->oPosVec, &dist); - return dist; + register Vec3f d; + vec3_diff(d, &obj2->oPosVec, &obj1->oPosVec); + return vec3_mag(d); } void cur_obj_forward_vel_approach_upward(f32 target, f32 increment) {