diff --git a/src/game/behaviors/intro_lakitu.inc.c b/src/game/behaviors/intro_lakitu.inc.c index a36f8614..0d538609 100644 --- a/src/game/behaviors/intro_lakitu.inc.c +++ b/src/game/behaviors/intro_lakitu.inc.c @@ -55,7 +55,7 @@ s32 intro_lakitu_set_pos_and_focus(struct Object *obj, struct CutsceneSplinePoin void bhv_intro_lakitu_loop(void) { Vec3f offset, fromPoint, toPoint; - s16 yawToCam; + s16 yawToCam; switch (gCurrentObject->oAction) { case 0: @@ -94,10 +94,18 @@ void bhv_intro_lakitu_loop(void) { cur_obj_play_sound_2(SOUND_ACTION_INTRO_UNK45E); break; #endif - case 73: gCurrentObject->oAnimState++; break; - case 74: gCurrentObject->oAnimState--; break; - case 82: gCurrentObject->oAnimState++; break; - case 84: gCurrentObject->oAnimState--; break; + case 73: + gCurrentObject->oAnimState += 1; + break; + case 74: + gCurrentObject->oAnimState -= 1; + break; + case 82: + gCurrentObject->oAnimState += 1; + break; + case 84: + gCurrentObject->oAnimState -= 1; + break; } #ifdef VERSION_EU if (gCurrentObject->oTimer == 446) @@ -155,14 +163,14 @@ void bhv_intro_lakitu_loop(void) { #else #define TIMER 98 #endif + if (gCurrentObject->oTimer == TIMER) { obj_mark_for_deletion(gCurrentObject); obj_mark_for_deletion(gCurrentObject->oIntroLakituCloud); } #ifndef VERSION_JP - if (gCurrentObject->oTimer == 14) { + if (gCurrentObject->oTimer == 14) cur_obj_play_sound_2(SOUND_ACTION_INTRO_UNK45F); - } #endif break; case 100: @@ -180,11 +188,13 @@ void bhv_intro_lakitu_loop(void) { case 101: vec3f_copy(toPoint, &gCurrentObject->oPosVec); if (gCurrentObject->oTimer > 60) { - gCurrentObject->oForwardVel = approach_f32_asymptotic(gCurrentObject->oForwardVel, -10.f, 0.05f); + gCurrentObject->oForwardVel = + approach_f32_asymptotic(gCurrentObject->oForwardVel, -10.f, 0.05f); gCurrentObject->oMoveAngleYaw += 0x78; gCurrentObject->oMoveAnglePitch += 0x40; - vec3f_get_yaw(toPoint, gCamera->pos, &yawToCam); - gCurrentObject->oFaceAngleYaw = camera_approach_s16_symmetric(gCurrentObject->oFaceAngleYaw, yawToCam, 0x200); + gCurrentObject->oFaceAngleYaw = camera_approach_s16_symmetric( + gCurrentObject->oFaceAngleYaw, (s16) calculate_yaw(toPoint, gCamera->pos), + 0x200); } if (gCurrentObject->oTimer > 105) { gCurrentObject->oAction++; diff --git a/src/game/camera.c b/src/game/camera.c index fd47d858..be8fb57a 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -893,11 +893,9 @@ void radial_camera_move(struct Camera *c) { s32 avoidStatus; f32 areaDistX = sMarioCamState->pos[0] - c->areaCenX; f32 areaDistZ = sMarioCamState->pos[2] - c->areaCenZ; - s16 yawOffset; // How much the camera's yaw changed - vec3f_get_yaw(sMarioCamState->pos, c->pos, &yawOffset); - yawOffset -= atan2s(areaDistZ, areaDistX); + s16 yawOffset = calculate_yaw(sMarioCamState->pos, c->pos) - atan2s(areaDistZ, areaDistX); if (yawOffset > maxAreaYaw) { yawOffset = maxAreaYaw; @@ -1321,14 +1319,14 @@ s32 update_parallel_tracking_camera(struct Camera *c, Vec3f focus, Vec3f pos) { // Check if the camera should go to the next path if (sParTrackPath[sParTrackIndex + 1].startOfPath != 0) { // get Mario's distance to the next path - vec3f_get_angle(sParTrackPath[sParTrackIndex + 1].pos, sParTrackPath[sParTrackIndex + 2].pos, &nextPitch, &nextYaw); + calculate_angles(sParTrackPath[sParTrackIndex + 1].pos, sParTrackPath[sParTrackIndex + 2].pos, &nextPitch, &nextYaw); vec3f_set_dist_and_angle(sParTrackPath[sParTrackIndex + 1].pos, nextPathPos, 400.f, nextPitch, nextYaw); - vec3f_get_dist_squared(marioPos, nextPathPos, &distToPrev); + distToPrev = calc_abs_dist_squared(marioPos, nextPathPos); // get Mario's distance to the previous path - vec3f_get_angle(sParTrackPath[sParTrackIndex + 1].pos, sParTrackPath[sParTrackIndex].pos, &prevPitch, &prevYaw); + calculate_angles(sParTrackPath[sParTrackIndex + 1].pos, sParTrackPath[sParTrackIndex].pos, &prevPitch, &prevYaw); vec3f_set_dist_and_angle(sParTrackPath[sParTrackIndex + 1].pos, prevPathPos, 400.f, prevPitch, prevYaw); - vec3f_get_dist_squared(marioPos, prevPathPos, &distToNext); + distToNext = calc_abs_dist_squared(marioPos, prevPathPos); if (distToPrev < distToNext) { sParTrackIndex++; sStatusFlags |= CAM_FLAG_CHANGED_PARTRACK_INDEX; @@ -1338,14 +1336,14 @@ s32 update_parallel_tracking_camera(struct Camera *c, Vec3f focus, Vec3f pos) { // Check if the camera should go to the previous path if (sParTrackIndex != 0) { // get Mario's distance to the next path - vec3f_get_angle((*(sParTrackPath + sParTrackIndex)).pos, (*(sParTrackPath + sParTrackIndex + 1)).pos, &nextPitch, &nextYaw); + calculate_angles((*(sParTrackPath + sParTrackIndex)).pos, (*(sParTrackPath + sParTrackIndex + 1)).pos, &nextPitch, &nextYaw); vec3f_set_dist_and_angle(sParTrackPath[sParTrackIndex].pos, nextPathPos, 700.f, nextPitch, nextYaw); - vec3f_get_dist_squared(marioPos, nextPathPos, &distToPrev); + distToPrev = calc_abs_dist_squared(marioPos, nextPathPos); // get Mario's distance to the previous path - vec3f_get_angle((*(sParTrackPath + sParTrackIndex)).pos, (*(sParTrackPath + sParTrackIndex - 1)).pos, &prevPitch, &prevYaw); + calculate_angles((*(sParTrackPath + sParTrackIndex)).pos, (*(sParTrackPath + sParTrackIndex - 1)).pos, &prevPitch, &prevYaw); vec3f_set_dist_and_angle(sParTrackPath[sParTrackIndex].pos, prevPathPos, 700.f, prevPitch, prevYaw); - vec3f_get_dist_squared(marioPos, prevPathPos, &distToNext); + distToNext = calc_abs_dist_squared(marioPos, prevPathPos); if (distToPrev > distToNext) { sParTrackIndex--; sStatusFlags |= CAM_FLAG_CHANGED_PARTRACK_INDEX; @@ -1484,9 +1482,7 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) { heldState = 0; } - vec3f_get_dist(sMarioCamState->pos, secondFocus, &focusDistance); - focusDistance *= 1.6f; - + focusDistance = calc_abs_dist(sMarioCamState->pos, secondFocus) * 1.6f; if (focusDistance < 800.f) { focusDistance = 800.f; } @@ -1878,7 +1874,8 @@ s16 update_slide_camera(struct Camera *c) { vec3f_set_dist_and_angle(c->focus, c->pos, distCamToFocus, camPitch, camYaw); } } - vec3f_get_yaw(c->focus, c->pos, &camYaw); + + camYaw = calculate_yaw(c->focus, c->pos); return camYaw; } @@ -1996,7 +1993,7 @@ s16 update_default_camera(struct Camera *c) { nextYawVel = 0; } sYawSpeed = 0x400; - vec3f_get_lateral_dist(sMarioCamState->pos, c->pos, &xzDist); + xzDist = calc_hor_dist(sMarioCamState->pos, c->pos); if (sStatusFlags & CAM_FLAG_BEHIND_MARIO_POST_DOOR) { if (xzDist >= 250) { @@ -2158,8 +2155,7 @@ s16 update_default_camera(struct Camera *c) { // Make Lakitu fly above the gas gasHeight = find_poison_gas_level(cPos[0], cPos[2]); if (gasHeight != FLOOR_LOWER_LIMIT) { - gasHeight += 130.f; - if (gasHeight > c->pos[1]) { + if ((gasHeight += 130.f) > c->pos[1]) { c->pos[1] = gasHeight; } } @@ -2245,14 +2241,23 @@ void mode_mario_camera(struct Camera *c) { * Rotates the camera around the spiral staircase. */ s32 update_spiral_stairs_camera(struct Camera *c, Vec3f focus, Vec3f pos) { + /// The returned yaw + s16 camYaw; + // unused + s16 focPitch; /// The focus (Mario)'s yaw around the stairs s16 focYaw; + // unused + s16 posPitch; /// The camera's yaw around the stairs s16 posYaw; Vec3f cPos; Vec3f checkPos; struct Surface *floor; - f32 focusHeight, floorHeight; + // unused + f32 dist; + f32 focusHeight; + f32 floorHeight; f32 focY; handle_c_button_movement(c); @@ -2266,8 +2271,8 @@ s32 update_spiral_stairs_camera(struct Camera *c, Vec3f focus, Vec3f pos) { focus[2] = sMarioCamState->pos[2]; vec3f_copy(cPos, pos); - vec3f_get_yaw(sFixedModeBasePosition, focus, &focYaw); - vec3f_get_yaw(sFixedModeBasePosition, cPos, &posYaw); + vec3f_get_dist_and_angle(sFixedModeBasePosition, focus, &dist, &focPitch, &focYaw); + vec3f_get_dist_and_angle(sFixedModeBasePosition, cPos, &dist, &posPitch, &posYaw); sSpiralStairsYawOffset = posYaw - focYaw; // posYaw will change if Mario is more than 90 degrees around the stairs, relative to the camera @@ -2283,9 +2288,9 @@ s32 update_spiral_stairs_camera(struct Camera *c, Vec3f focus, Vec3f pos) { vec3f_set_dist_and_angle(sFixedModeBasePosition, cPos, 300.f, 0, posYaw); // Move the camera's y coord up/down the staircase - checkPos[0] = focus[0] + ((cPos[0] - focus[0]) * 0.7f); - checkPos[1] = focus[1] + ((cPos[1] - focus[1]) * 0.7f) + 300.f; - checkPos[2] = focus[2] + ((cPos[2] - focus[2]) * 0.7f); + checkPos[0] = focus[0] + (cPos[0] - focus[0]) * 0.7f; + checkPos[1] = focus[1] + (cPos[1] - focus[1]) * 0.7f + 300.f; + checkPos[2] = focus[2] + (cPos[2] - focus[2]) * 0.7f; floorHeight = find_floor(checkPos[0], checkPos[1] + 50.f, checkPos[2], &floor); if (floorHeight != FLOOR_LOWER_LIMIT) { @@ -2298,8 +2303,9 @@ s32 update_spiral_stairs_camera(struct Camera *c, Vec3f focus, Vec3f pos) { camera_approach_f32_symmetric_bool(&focus[1], focY, 30.f); pos[0] = cPos[0]; pos[2] = cPos[2]; - vec3f_get_yaw(focus, pos, &posYaw); - return posYaw; + camYaw = calculate_yaw(focus, pos); + + return camYaw; } /** @@ -2376,8 +2382,15 @@ void exit_c_up(struct Camera *c) { f32 d; s16 curPitch, curYaw; s16 checkYaw = 0; + Vec3f storePos; // unused + Vec3f storeFoc; // unused if ((gCameraMovementFlags & CAM_MOVE_C_UP_MODE) && !(gCameraMovementFlags & CAM_MOVE_STARTED_EXITING_C_UP)) { + // Copy the stored pos and focus. This is unused. + vec3f_copy(storePos, sCameraStoreCUp.pos); + vec3f_add(storePos, sMarioCamState->pos); + vec3f_copy(storeFoc, sCameraStoreCUp.focus); + vec3f_add(storeFoc, sMarioCamState->pos); vec3f_copy(checkFoc, c->focus); checkFoc[0] = sMarioCamState->pos[0]; @@ -3196,7 +3209,7 @@ void init_camera(struct Camera *c) { set_fixed_cam_axis_sa_lobby(c->mode); } store_lakitu_cam_info_for_c_up(c); - vec3f_get_yaw(c->focus, c->pos, &gLakituState.yaw); + gLakituState.yaw = calculate_yaw(c->focus, c->pos); gLakituState.nextYaw = gLakituState.yaw; c->yaw = gLakituState.yaw; c->nextYaw = gLakituState.yaw; @@ -3223,6 +3236,8 @@ void init_camera(struct Camera *c) { * modulo-4's the result, because each 8-bit mask only has 4 area bits for each level */ void zoom_out_if_paused_and_outside(struct GraphNodeCamera *camera) { + UNUSED f32 dist; + UNUSED s16 pitch; s16 yaw; s32 areaMaskIndex = gCurrLevelArea / 32; s32 areaBit = 1 << (((gCurrLevelArea & 0x10) / 4) + (((gCurrLevelArea & 0xF) - 1) & 3)); @@ -3238,7 +3253,7 @@ void zoom_out_if_paused_and_outside(struct GraphNodeCamera *camera) { camera->focus[0] = gCamera->areaCenX; camera->focus[1] = (sMarioCamState->pos[1] + gCamera->areaCenY) / 2; camera->focus[2] = gCamera->areaCenZ; - vec3f_get_yaw(camera->focus, sMarioCamState->pos, &yaw); + vec3f_get_dist_and_angle(camera->focus, sMarioCamState->pos, &dist, &pitch, &yaw); vec3f_set_dist_and_angle(sMarioCamState->pos, camera->pos, 6000.f, 0x1000, yaw); #ifndef DISABLE_LEVEL_SPECIFIC_CHECKS if (gCurrLevelNum != LEVEL_THI) { @@ -3463,13 +3478,34 @@ s32 set_cam_angle(s32 mode) { */ void set_handheld_shake(u8 mode) { switch (mode) { - case HAND_CAM_SHAKE_CUTSCENE: sHandheldShakeMag = 0x600; sHandheldShakeInc = 0.04f; break; // Lowest increment - case HAND_CAM_SHAKE_UNUSED: sHandheldShakeMag = 0x600; sHandheldShakeInc = 0.07f; break; // Never used - case HAND_CAM_SHAKE_HANG_OWL: sHandheldShakeMag = 0x600; sHandheldShakeInc = 0.07f; break; // exactly the same as UNUSED... - case HAND_CAM_SHAKE_HIGH: sHandheldShakeMag = 0x1000; sHandheldShakeInc = 0.1f; break; // Highest mag and inc - case HAND_CAM_SHAKE_STAR_DANCE: sHandheldShakeMag = 0x400; sHandheldShakeInc = 0.07f; break; // Slightly steadier than HANG_OWL and UNUSED - case HAND_CAM_SHAKE_LOW: sHandheldShakeMag = 0x300; sHandheldShakeInc = 0.06f; break; // Lowest magnitude - default: sHandheldShakeMag = 0x0; sHandheldShakeInc = 0.f; + // They're not in numerical order because that would be too simple... + case HAND_CAM_SHAKE_CUTSCENE: // Lowest increment + sHandheldShakeMag = 0x600; + sHandheldShakeInc = 0.04f; + break; + case HAND_CAM_SHAKE_LOW: // Lowest magnitude + sHandheldShakeMag = 0x300; + sHandheldShakeInc = 0.06f; + break; + case HAND_CAM_SHAKE_HIGH: // Highest mag and inc + sHandheldShakeMag = 0x1000; + sHandheldShakeInc = 0.1f; + break; + case HAND_CAM_SHAKE_UNUSED: // Never used + sHandheldShakeMag = 0x600; + sHandheldShakeInc = 0.07f; + break; + case HAND_CAM_SHAKE_HANG_OWL: // exactly the same as UNUSED... + sHandheldShakeMag = 0x600; + sHandheldShakeInc = 0.07f; + break; + case HAND_CAM_SHAKE_STAR_DANCE: // Slightly steadier than HANG_OWL and UNUSED + sHandheldShakeMag = 0x400; + sHandheldShakeInc = 0.07f; + break; + default: + sHandheldShakeMag = 0x0; + sHandheldShakeInc = 0.f; } } @@ -3627,7 +3663,7 @@ s32 collide_with_walls(Vec3f pos, f32 offsetY, f32 radius) { normZ = wall->normal.z; originOffset = wall->originOffset; offset = normX * newPos[i][0] + normY * newPos[i][1] + normZ * newPos[i][2] + originOffset; - offsetAbsolute = ABS(offset); + offsetAbsolute = ABS2(offset); if (offsetAbsolute < radius) { newPos[i][0] += normX * (radius - offset); newPos[i][2] += normZ * (radius - offset); @@ -3654,10 +3690,9 @@ void clamp_pitch(Vec3f from, Vec3f to, s16 maxPitch, s16 minPitch) { } s32 is_within_100_units_of_mario(f32 posX, f32 posY, f32 posZ) { - Vec3f pos = { posX, posY, posZ }; - f32 dist; - vec3f_get_dist_squared(sMarioCamState->pos, pos, &dist); - return (dist < sqr(100.f)); + Vec3f pos; + vec3f_set(pos, posX, posY, posZ); + return (calc_abs_dist_squared(sMarioCamState->pos, pos) < sqr(100.f)); } s32 set_or_approach_f32_asymptotic(f32 *dst, f32 goal, f32 scale) { @@ -3807,7 +3842,7 @@ s16 reduce_by_dist_from_camera(s16 value, f32 maxDist, f32 posX, f32 posY, f32 p pos[2] = posZ; vec3f_get_dist_and_angle(gLakituState.goalPos, pos, &dist, &pitch, &yaw); if (dist < maxDist) { - vec3f_get_angle(gLakituState.goalPos, gLakituState.goalFocus, &goalPitch, &goalYaw); + calculate_angles(gLakituState.goalPos, gLakituState.goalFocus, &goalPitch, &goalYaw); pitch -= goalPitch; yaw -= goalYaw; dist -= 2000.f; @@ -3830,11 +3865,20 @@ s16 reduce_by_dist_from_camera(s16 value, f32 maxDist, f32 posX, f32 posY, f32 p s32 clamp_positions_and_find_yaw(Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, f32 zMin) { s16 yaw = gCamera->nextYaw; - if (pos[0] >= xMax) pos[0] = xMax; - if (pos[0] <= xMin) pos[0] = xMin; - if (pos[2] >= zMax) pos[2] = zMax; - if (pos[2] <= zMin) pos[2] = zMin; - vec3f_get_yaw(origin, pos, &yaw); + + if (pos[0] >= xMax) { + pos[0] = xMax; + } + if (pos[0] <= xMin) { + pos[0] = xMin; + } + if (pos[2] >= zMax) { + pos[2] = zMax; + } + if (pos[2] <= zMin) { + pos[2] = zMin; + } + yaw = calculate_yaw(origin, pos); return yaw; } @@ -3849,7 +3893,9 @@ s32 clamp_positions_and_find_yaw(Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f3 * developers just add 180 degrees to the result. */ s32 calc_avoid_yaw(s16 yawFromMario, s16 wallYaw) { - if ((s16)(wallYaw - yawFromMario + DEGREES(90)) < 0) { + s16 yawDiff = wallYaw - yawFromMario + DEGREES(90); + + if (yawDiff < 0) { // Deflect to the right yawFromMario = wallYaw; } else { @@ -3892,14 +3938,22 @@ s32 is_surf_within_bounding_box(struct Surface *surf, f32 xMax, f32 yMax, f32 zM sz[2] = surf->vertex3[2]; for (i = 0; i < 3; i++) { - j = (i + 1); - if (j >= 3) j = 0; + j = i + 1; + if (j >= 3) { + j = 0; + } dx = ABS(sx[i] - sx[j]); - if (dx > dxMax) dxMax = dx; + if (dx > dxMax) { + dxMax = dx; + } dy = ABS(sy[i] - sy[j]); - if (dy > dyMax) dyMax = dy; + if (dy > dyMax) { + dyMax = dy; + } dz = ABS(sz[i] - sz[j]); - if (dz > dzMax) dzMax = dz; + if (dz > dzMax) { + dzMax = dz; + } } if (yMax != -1.f) { if (dyMax < yMax) { @@ -3993,6 +4047,56 @@ s32 is_pos_in_bounds(Vec3f pos, Vec3f center, Vec3f bounds, s16 boundsYaw) { -bounds[2] < rel[2] && rel[2] < bounds[2]); } +s16 calculate_pitch(Vec3f from, Vec3f to) { + f32 dx = to[0] - from[0]; + f32 dy = to[1] - from[1]; + f32 dz = to[2] - from[2]; + return atan2s(sqrtf(sqr(dx) + sqr(dz)), dy); +} + +s16 calculate_yaw(Vec3f from, Vec3f to) { + f32 dx = to[0] - from[0]; + f32 dz = to[2] - from[2]; + return atan2s(dz, dx); +} + +/** + * Calculates the pitch and yaw between two vectors. + */ +void calculate_angles(Vec3f from, Vec3f to, s16 *pitch, s16 *yaw) { + f32 dx = to[0] - from[0]; + f32 dy = to[1] - from[1]; + f32 dz = to[2] - from[2]; + *pitch = atan2s(sqrtf(sqr(dx) + sqr(dz)), dy); + *yaw = atan2s(dz, dx); +} + +/** + * Finds the distance between two vectors. + */ +f32 calc_abs_dist(Vec3f a, Vec3f b) { + register f32 distX = b[0] - a[0]; + register f32 distY = b[1] - a[1]; + register f32 distZ = b[2] - a[2]; + return sqrtf(sqr(distX) + sqr(distY) + sqr(distZ)); +} + +f32 calc_abs_dist_squared(Vec3f a, Vec3f b) { + register f32 distX = b[0] - a[0]; + register f32 distY = b[1] - a[1]; + register f32 distZ = b[2] - a[2]; + return (sqr(distX) + sqr(distY) + sqr(distZ)); +} + +/** + * Finds the horizontal distance between two vectors. + */ +f32 calc_hor_dist(Vec3f a, Vec3f b) { + register f32 distX = b[0] - a[0]; + register f32 distZ = b[2] - a[2]; + return sqrtf(sqr(distX) + sqr(distZ)); +} + /** * Rotates a vector in the horizontal plane and copies it to a new vector. */ @@ -4140,7 +4244,6 @@ void shake_camera_roll(s16 *roll) { s32 offset_yaw_outward_radial(struct Camera *c, s16 areaYaw) { s16 yawGoal = DEGREES(60); s16 yaw = sModeOffsetYaw; - f32 distFromAreaCenter; Vec3f areaCenter; s16 dYaw; switch (gCurrLevelArea) { @@ -4148,8 +4251,7 @@ s32 offset_yaw_outward_radial(struct Camera *c, s16 areaYaw) { areaCenter[0] = c->areaCenX; areaCenter[1] = sMarioCamState->pos[1]; areaCenter[2] = c->areaCenZ; - vec3f_get_dist_squared(areaCenter, sMarioCamState->pos, &distFromAreaCenter); - if (sqr(800.f) > distFromAreaCenter) { + if (sqr(800.f) > calc_abs_dist_squared(areaCenter, sMarioCamState->pos)) { yawGoal = 0x3800; } break; @@ -4711,13 +4813,18 @@ void determine_pushing_or_pulling_door(s16 *rotation) { */ s16 next_lakitu_state(Vec3f newPos, Vec3f newFoc, Vec3f curPos, Vec3f curFoc, Vec3f oldPos, Vec3f oldFoc, s16 yaw) { - s16 pitchVelocity, yawVelocity; + s16 yawVelocity; + s16 pitchVelocity; f32 distVelocity; f32 goalDist; - s16 goalPitch, goalYaw; + s16 goalPitch; + s16 goalYaw; f32 distTimer = sModeTransition.framesLeft; s16 angleTimer = sModeTransition.framesLeft; - Vec3f startPos, nextPos, startFoc, nextFoc; + Vec3f nextPos; + Vec3f nextFoc; + Vec3f startPos; + Vec3f startFoc; s32 i; f32 floorHeight; struct Surface *floor; @@ -4735,8 +4842,10 @@ s16 next_lakitu_state(Vec3f newPos, Vec3f newFoc, Vec3f curPos, Vec3f curFoc, } - vec3f_get_dist_and_angle(curFoc, startFoc, &sModeTransition.focDist, &sModeTransition.focPitch, &sModeTransition.focYaw); - vec3f_get_dist_and_angle(curFoc, startPos, &sModeTransition.posDist, &sModeTransition.posPitch, &sModeTransition.posYaw); + vec3f_get_dist_and_angle(curFoc, startFoc, &sModeTransition.focDist, &sModeTransition.focPitch, + &sModeTransition.focYaw); + vec3f_get_dist_and_angle(curFoc, startPos, &sModeTransition.posDist, &sModeTransition.posPitch, + &sModeTransition.posYaw); sStatusFlags &= ~CAM_FLAG_START_TRANSITION; } @@ -4777,7 +4886,7 @@ s16 next_lakitu_state(Vec3f newPos, Vec3f newFoc, Vec3f curPos, Vec3f curFoc, f32_find_wall_collision(&newPos[0], &newPos[1], &newPos[2], 0.f, 100.f); } sModeTransition.framesLeft--; - vec3f_get_yaw(newFoc, newPos, &yaw); + yaw = calculate_yaw(newFoc, newPos); } else { sModeTransition.posDist = 0.f; sModeTransition.posPitch = 0; @@ -4853,15 +4962,13 @@ void set_camera_mode_close_cam(u8 *mode) { */ void set_camera_mode_radial(struct Camera *c, s16 transitionTime) { Vec3f focus; - s16 yawToMario, yawToCam, yaw; + s16 yaw; focus[0] = c->areaCenX; focus[1] = sMarioCamState->pos[1]; focus[2] = c->areaCenZ; if (c->mode != CAMERA_MODE_RADIAL) { - vec3f_get_yaw(focus, sMarioCamState->pos, &yawToMario); - vec3f_get_yaw(c->focus, c->pos, &yawToCam); - yaw = yawToMario - yawToCam + DEGREES(90); + yaw = calculate_yaw(focus, sMarioCamState->pos) - calculate_yaw(c->focus, c->pos) + DEGREES(90); if (yaw > 0) { transition_to_camera_mode(c, CAMERA_MODE_RADIAL, transitionTime); } else { @@ -5802,6 +5909,7 @@ s16 camera_course_processing(struct Camera *c) { // Camera trigger's bounding box Vec3f center, bounds; u32 insideBounds = FALSE; + UNUSED struct CameraTrigger unused; u8 oldMode = c->mode; if (c->mode == CAMERA_MODE_C_UP) { @@ -5849,7 +5957,8 @@ s16 camera_course_processing(struct Camera *c) { } } } - b++; + + b += 1; } } #if !defined(CAMERA_FIX) && !defined(DISABLE_LEVEL_SPECIFIC_CHECKS) @@ -5920,14 +6029,18 @@ s16 camera_course_processing(struct Camera *c) { break; case AREA_WDW_MAIN: - if (sMarioGeometry.currFloorType == SURFACE_INSTANT_WARP_1B) { - c->defMode = CAMERA_MODE_RADIAL; + switch (sMarioGeometry.currFloorType) { + case SURFACE_INSTANT_WARP_1B: + c->defMode = CAMERA_MODE_RADIAL; + break; } break; case AREA_WDW_TOWN: - if (sMarioGeometry.currFloorType == SURFACE_INSTANT_WARP_1C) { - c->defMode = CAMERA_MODE_CLOSE; + switch (sMarioGeometry.currFloorType) { + case SURFACE_INSTANT_WARP_1C: + c->defMode = CAMERA_MODE_CLOSE; + break; } break; @@ -6207,7 +6320,7 @@ s16 cutscene_object(u8 cutscene, struct Object *obj) { * Update the camera's yaw and nextYaw. This is called from cutscenes to ignore the camera mode's yaw. */ void update_camera_yaw(struct Camera *c) { - vec3f_get_yaw(c->focus, c->pos, &c->nextYaw); + c->nextYaw = calculate_yaw(c->focus, c->pos); c->yaw = c->nextYaw; } @@ -6445,7 +6558,7 @@ void rotate_and_move_vec3f(Vec3f to, Vec3f from, f32 incDist, s16 incPitch, s16 void set_flag_post_door(struct Camera *c) { sStatusFlags |= CAM_FLAG_BEHIND_MARIO_POST_DOOR; - vec3f_get_yaw(c->focus, c->pos, &sCameraYawAfterDoorCutscene); + sCameraYawAfterDoorCutscene = calculate_yaw(c->focus, c->pos); } void cutscene_soften_music(UNUSED struct Camera *c) { @@ -7110,7 +7223,7 @@ void cutscene_dance_fly_away_start(struct Camera *c) { if (c->mode == CAMERA_MODE_RADIAL) { vec3f_set(areaCenter, c->areaCenX, c->areaCenY, c->areaCenZ); - vec3f_get_yaw(areaCenter, c->pos, &c->yaw); + c->yaw = calculate_yaw(areaCenter, c->pos); c->nextYaw = c->yaw; } @@ -7566,8 +7679,8 @@ void cutscene_red_coin_star_warp(struct Camera *c) { vec3f_copy(sCutsceneVars[1].point, &gCutsceneFocus->oHomeVec); vec3f_get_dist_and_angle(sCutsceneVars[1].point, c->pos, &dist, &pitch, &yaw); - vec3f_get_yaw(sCutsceneVars[1].point, c->pos, &posYaw); - vec3f_get_yaw(sCutsceneVars[1].point, sMarioCamState->pos, &yaw); + posYaw = calculate_yaw(sCutsceneVars[1].point, c->pos); + yaw = calculate_yaw(sCutsceneVars[1].point, sMarioCamState->pos); if (ABS(yaw - posYaw + DEGREES(90)) < ABS(yaw - posYaw - DEGREES(90))) { yaw += DEGREES(90); @@ -8100,8 +8213,9 @@ void cutscene_dialog_start(struct Camera *c) { // Store gCutsceneFocus's position and yaw vec3f_copy(sCutsceneVars[9].point, &gCutsceneFocus->oPosVec); sCutsceneVars[9].point[1] += gCutsceneFocus->hitboxHeight + 200.f; - vec3f_get_yaw(sCutsceneVars[8].point, sCutsceneVars[9].point, &sCutsceneVars[9].angle[1]); - vec3f_get_yaw(sMarioCamState->pos, gLakituState.curPos, &yaw); + sCutsceneVars[9].angle[1] = calculate_yaw(sCutsceneVars[8].point, sCutsceneVars[9].point); + + yaw = calculate_yaw(sMarioCamState->pos, gLakituState.curPos); if ((yaw - sCutsceneVars[9].angle[1]) & 0x8000) { sCutsceneVars[9].angle[1] -= 0x6000; } else { @@ -8120,7 +8234,7 @@ void cutscene_dialog_move_mario_shoulder(struct Camera *c) { scale_along_line(focus, sCutsceneVars[9].point, sMarioCamState->pos, 0.7f); vec3f_get_dist_and_angle(c->pos, focus, &dist, &pitch, &yaw); - vec3f_get_pitch(c->pos, sCutsceneVars[9].point, &pitch); + pitch = calculate_pitch(c->pos, sCutsceneVars[9].point); vec3f_set_dist_and_angle(c->pos, pos, dist, pitch, yaw); focus[1] = focus[1] + (sCutsceneVars[9].point[1] - focus[1]) * 0.1f; @@ -8136,8 +8250,8 @@ void cutscene_dialog_move_mario_shoulder(struct Camera *c) { vec3f_set_dist_and_angle(sCutsceneVars[8].point, pos, dist, pitch, yaw); // Move up if Mario is below the focus object, down is Mario is above - vec3f_get_pitch(sCutsceneVars[9].point, sCutsceneVars[8].point, &pitch); - pos[1] = sCutsceneVars[8].point[1] + (sins(pitch) * 100.f); + pos[1] = sCutsceneVars[8].point[1] + + sins(calculate_pitch(sCutsceneVars[9].point, sCutsceneVars[8].point)) * 100.f; approach_f32_asymptotic_bool(&c->pos[1], pos[1], 0.05f); c->pos[0] = pos[0]; @@ -8477,9 +8591,8 @@ void cutscene_non_painting_death(struct Camera *c) { * because cvar1 rotates until is reaches 0, so it's important that it's a multiple of 0x100. */ void cutscene_cap_switch_press_start(struct Camera *c) { - s16 yaw; store_info_star(c); - vec3f_get_yaw(sMarioCamState->pos, c->pos, &yaw); + s16 yaw = calculate_yaw(sMarioCamState->pos, c->pos); sCutsceneVars[3].angle[1] = 0x1200; // Basically the amount of rotation to get from behind Mario to in front of Mario sCutsceneVars[1].angle[1] = (yaw - (sMarioCamState->faceAngle[1] + sCutsceneVars[3].angle[1])) & 0xFF00; diff --git a/src/game/camera.h b/src/game/camera.h index c18e8d56..5b839d71 100644 --- a/src/game/camera.h +++ b/src/game/camera.h @@ -21,6 +21,7 @@ * @see camera.c */ +#define ABS2(x) ((x) >= 0.f ? (x) : -(x)) #define LEVEL_AREA_INDEX(levelNum, areaNum) (((levelNum) << 4) + (areaNum)) /** @@ -703,6 +704,12 @@ void random_vec3s(Vec3s dst, s16 xRange, s16 yRange, s16 zRange); s32 clamp_positions_and_find_yaw(Vec3f pos, Vec3f origin, f32 xMax, f32 xMin, f32 zMax, f32 zMin); s32 is_range_behind_surface(Vec3f from, Vec3f to, struct Surface *surf, s16 range, s16 surfType); void scale_along_line(Vec3f dest, Vec3f from, Vec3f to, f32 scale); +s16 calculate_pitch(Vec3f from, Vec3f to); +s16 calculate_yaw(Vec3f from, Vec3f to); +void calculate_angles(Vec3f from, Vec3f to, s16 *pitch, s16 *yaw); +f32 calc_abs_dist(Vec3f a, Vec3f b); +f32 calc_abs_dist_squared(Vec3f a, Vec3f b); +f32 calc_hor_dist(Vec3f a, Vec3f b); void rotate_in_xz(Vec3f dst, Vec3f src, s16 yaw); void rotate_in_yz(Vec3f dst, Vec3f src, s16 pitch); void set_camera_pitch_shake(s16 mag, s16 decay, s16 inc);