From cbd0c05447ee37d7fa2af516eb076a76afa73f1d Mon Sep 17 00:00:00 2001 From: Anoliah <173389381+Anoliah@users.noreply.github.com> Date: Thu, 30 Oct 2025 19:20:47 -0700 Subject: [PATCH] rework vanilla camera overrides (#873) --- include/config/config_camera.h | 17 +---- include/config/config_safeguards.h | 5 ++ src/game/camera.c | 99 +++++++++++++----------------- 3 files changed, 49 insertions(+), 72 deletions(-) diff --git a/include/config/config_camera.h b/include/config/config_camera.h index 3fea62ba1..0e4b5cbb6 100644 --- a/include/config/config_camera.h +++ b/include/config/config_camera.h @@ -6,10 +6,7 @@ /** * Forces the camera mode to your choice (except when swimming or flying). - * It does this by setting the area's camera->defMode to this mode, and also - * changes hardcoded modes to use c->defMode. - * Note: removes door cutscenes due to the way they're designed to work with specific modes. - * Search for FORCED_CAMERA_MODE in camera.c for more information. + * It does this by setting the area's camera->defMode to this mode. */ #define FORCED_CAMERA_MODE CAMERA_MODE_8_DIRECTIONS @@ -60,17 +57,9 @@ /***** Vanilla config options *****/ /**********************************/ -/** - * Included for ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS define. - */ -#include "config_game.h" - /** * Allow course specific camera processing. * You will likely want this disabled in non-vanilla hacks. - * This is automatically enabled when ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS is enabled, - * but feel free to override it if you really want to for some reason. + * Enabling this will automatically disable FORCED_CAMERA_MODE and USE_COURSE_DEFAULT_MODE. */ -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS - #define ENABLE_VANILLA_CAM_PROCESSING -#endif +// #define ENABLE_VANILLA_CAM_PROCESSING diff --git a/include/config/config_safeguards.h b/include/config/config_safeguards.h index 6fb47fc08..cf64afa8f 100644 --- a/include/config/config_safeguards.h +++ b/include/config/config_safeguards.h @@ -122,6 +122,11 @@ * config_camera.h */ +#ifdef ENABLE_VANILLA_CAM_PROCESSING + #undef FORCED_CAMERA_MODE + #undef USE_COURSE_DEFAULT_MODE +#endif // ENABLE_VANILLA_CAM_PROCESSING + #ifdef FORCED_CAMERA_MODE #undef USE_COURSE_DEFAULT_MODE #define USE_COURSE_DEFAULT_MODE // Forced camera mode overwrites the default mode. diff --git a/src/game/camera.c b/src/game/camera.c index 8cd629d0a..2804f1f20 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -823,7 +823,7 @@ void pan_ahead_of_player(struct Camera *c) { vec3f_add(c->focus, pan); } -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING s16 find_in_bounds_yaw_wdw_bob_thi(Vec3f pos, Vec3f origin, s16 yaw) { switch (gCurrLevelArea) { case AREA_WDW_MAIN: @@ -841,7 +841,7 @@ s16 find_in_bounds_yaw_wdw_bob_thi(Vec3f pos, Vec3f origin, s16 yaw) { } return yaw; } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING /** * Rotates the camera around the area's center point. @@ -858,9 +858,9 @@ s32 update_radial_camera(struct Camera *c, Vec3f focus, Vec3f pos) { sAreaYaw = camYaw - sModeOffsetYaw; calc_y_to_curr_floor(&posY, 1.f, 200.f, &focusY, 0.9f, 200.f); focus_on_mario(focus, pos, posY + yOff, focusY + yOff, sLakituDist + baseDist, pitch, camYaw); -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING camYaw = find_in_bounds_yaw_wdw_bob_thi(pos, focus, camYaw); -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING return camYaw; } @@ -879,11 +879,11 @@ s32 update_8_directions_camera(struct Camera *c, Vec3f focus, Vec3f pos) { calc_y_to_curr_floor(&posY, 1.f, 200.f, &focusY, 0.9f, 200.f); focus_on_mario(focus, pos, posY + yOff, focusY + yOff, sLakituDist + baseDist, pitch, camYaw); pan_ahead_of_player(c); -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelArea == AREA_DDD_SUB) { camYaw = clamp_positions_and_find_yaw(pos, focus, 6839.f, 995.f, 5994.f, -3945.f); } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING return camYaw; } @@ -1534,7 +1534,7 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) { nz = floor->normal.z; oo = floor->originOffset; pos[1] = 300.f - (nx * pos[0] + nz * pos[2] + oo) / ny; -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING switch (gCurrLevelArea) { case AREA_BOB: pos[1] += 125.f; @@ -1543,14 +1543,14 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) { case AREA_WF: pos[1] += 125.f; } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING } -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING // Prevent the camera from going to the ground in the outside boss fight if (gCurrLevelNum == LEVEL_BBH) { pos[1] = 2047.f; } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING // Rotate from C-Button input if (sCSideButtonYaw < 0) { sModeOffsetYaw += 0x200; @@ -1635,13 +1635,13 @@ void mode_parallel_tracking_camera(struct Camera *c) { * Fixed camera mode, the camera rotates around a point and looks and zooms toward Mario. */ void mode_fixed_camera(struct Camera *c) { -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelNum == LEVEL_BBH) { set_fov_function(CAM_FOV_BBH); } else { set_fov_function(CAM_FOV_APP_45); } -#else +#else // ENABLE_VANILLA_CAM_PROCESSING set_fov_function(CAM_FOV_APP_45); #endif c->nextYaw = update_fixed_camera(c, c->focus, c->pos); @@ -1778,7 +1778,7 @@ s32 update_behind_mario_camera(struct Camera *c, Vec3f focus, Vec3f pos) { dist = 300.f; } vec3f_set_dist_and_angle(focus, pos, dist, pitch, yaw); -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelArea == AREA_WDW_MAIN) { yaw = clamp_positions_and_find_yaw(pos, focus, 4508.f, -3739.f, 4508.f, -3739.f); } @@ -1788,7 +1788,7 @@ s32 update_behind_mario_camera(struct Camera *c, Vec3f focus, Vec3f pos) { if (gCurrLevelArea == AREA_THI_TINY) { yaw = clamp_positions_and_find_yaw(pos, focus, 2458.f, -2458.f, 2458.f, -2458.f); } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING return yaw; } @@ -2202,11 +2202,11 @@ s16 update_default_camera(struct Camera *c) { } if ((gCameraMovementFlags & CAM_MOVE_ZOOMED_OUT) && (sSelectionFlags & CAM_MODE_MARIO_ACTIVE)) { posHeight = 610.f; -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelArea == AREA_SSL_PYRAMID || gCurrLevelNum == LEVEL_CASTLE) { posHeight /= 2; } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING } // Make Lakitu fly above the gas @@ -2262,11 +2262,11 @@ s16 update_default_camera(struct Camera *c) { c->pos[1] = ceilHeight; } } -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelArea == AREA_WDW_TOWN) { yaw = clamp_positions_and_find_yaw(c->pos, c->focus, 2254.f, -3789.f, 3790.f, -2253.f); } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING return yaw; } @@ -2920,11 +2920,9 @@ void update_camera(struct Camera *c) { c->nextYaw = gLakituState.nextYaw; c->mode = gLakituState.mode; c->defMode = gLakituState.defMode; -#ifdef ENABLE_VANILLA_CAM_PROCESSING + camera_course_processing(c); -#else - if (gCurrDemoInput != NULL) camera_course_processing(c); -#endif + sCButtonsPressed = find_c_buttons_pressed(sCButtonsPressed, gPlayer1Controller->buttonPressed, gPlayer1Controller->buttonDown); if (c->cutscene != CUTSCENE_NONE) { @@ -3035,9 +3033,9 @@ void update_camera(struct Camera *c) { #ifdef PUPPYCAM if (!gPuppyCam.enabled || c->cutscene != 0 || gCurrentArea->camera->mode == CAMERA_MODE_INSIDE_CANNON) { #endif -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelNum != LEVEL_CASTLE) { -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING // If fixed camera is selected as the alternate mode, then fix the camera as long as the right // trigger is held if ((c->cutscene == CUTSCENE_NONE && @@ -3067,13 +3065,13 @@ void update_camera(struct Camera *c) { sCameraSoundFlags &= ~CAM_SOUND_FIXED_ACTIVE; } } -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING } else { if ((gPlayer1Controller->buttonPressed & R_TRIG) && (cam_select_alt_mode(0) == CAM_SELECTION_FIXED)) { play_sound_button_change_blocked(); } } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING update_lakitu(c); #ifdef PUPPYCAM @@ -3371,11 +3369,11 @@ void zoom_out_if_paused_and_outside(struct GraphNodeCamera *camera) { camera->focus[2] = gCamera->areaCenZ; vec3f_get_yaw(camera->focus, sMarioCamState->pos, &yaw); vec3f_set_dist_and_angle(sMarioCamState->pos, camera->pos, 6000.f, 0x1000, yaw); -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelNum != LEVEL_THI) { find_in_bounds_yaw_wdw_bob_thi(camera->pos, camera->focus, 0); } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING } } else { sFramesPaused++; @@ -5300,26 +5298,23 @@ void set_fixed_cam_axis_sa_lobby(UNUSED s16 preset) { * Only block area mode changes if Mario is in a cannon, * or if the camera is in Mario mode and Mario is not swimming or in water with the metal cap */ -#ifdef ENABLE_VANILLA_CAM_PROCESSING void check_blocking_area_processing(const u8 *mode) { if (sMarioCamState->action & ACT_FLAG_METAL_WATER || *mode == DEEP_WATER_CAMERA_MODE || *mode == WATER_SURFACE_CAMERA_MODE) { sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; } - + +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelNum == LEVEL_DDD || gCurrLevelNum == LEVEL_WDW || gCurrLevelNum == LEVEL_COTMC) { sStatusFlags &= ~CAM_FLAG_BLOCK_AREA_PROCESSING; } +#endif // ENABLE_VANILLA_CAM_PROCESSING if ((*mode == DEEP_WATER_CAMERA_MODE && !(sMarioCamState->action & (ACT_FLAG_SWIMMING | ACT_FLAG_METAL_WATER))) || *mode == CAMERA_MODE_INSIDE_CANNON) { sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; } -#else -void check_blocking_area_processing(UNUSED const u8 *mode) { - sStatusFlags |= CAM_FLAG_BLOCK_AREA_PROCESSING; -#endif } void cam_rr_exit_building_side(struct Camera *c) { @@ -6250,7 +6245,7 @@ s16 camera_course_processing(struct Camera *c) { b++; } } -#if defined(ENABLE_VANILLA_CAM_PROCESSING) && !defined(FORCED_CAMERA_MODE) && !defined(USE_COURSE_DEFAULT_MODE) +#ifdef ENABLE_VANILLA_CAM_PROCESSING // Area-specific camera processing if (!(sStatusFlags & CAM_FLAG_BLOCK_AREA_PROCESSING)) { switch (gCurrLevelArea) { @@ -6358,7 +6353,7 @@ s16 camera_course_processing(struct Camera *c) { break; } } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING sStatusFlags &= ~CAM_FLAG_BLOCK_AREA_PROCESSING; if (oldMode == CAMERA_MODE_C_UP) { @@ -7423,7 +7418,7 @@ void star_dance_bound_yaw(struct Camera *c, s16 absYaw, s16 yawMax) { * Store the camera's focus in cvar9. */ void cutscene_dance_closeup_start(struct Camera *c) { -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if ((gLastCompletedStarNum == 4) && (gCurrCourseNum == COURSE_JRB)) { star_dance_bound_yaw(c, 0x0, 0x4000); } @@ -7433,7 +7428,7 @@ void cutscene_dance_closeup_start(struct Camera *c) { if ((gLastCompletedStarNum == 5) && (gCurrCourseNum == COURSE_WDW)) { star_dance_bound_yaw(c, 0x8000, 0x800); } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING vec3f_copy(sCutsceneVars[9].point, c->focus); //! cvar8 is unused in the closeup cutscene @@ -7458,12 +7453,12 @@ void cutscene_dance_closeup_fly_above(struct Camera *c) { s16 pitch, yaw; f32 dist; s16 goalPitch = 0x1800; -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if ((gLastCompletedStarNum == 6 && gCurrCourseNum == COURSE_SL) || (gLastCompletedStarNum == 4 && gCurrCourseNum == COURSE_TTC)) { goalPitch = 0x800; } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING vec3f_get_dist_and_angle(sMarioCamState->pos, c->pos, &dist, &pitch, &yaw); approach_f32_asymptotic_bool(&dist, 800.f, 0.05f); approach_s16_asymptotic_bool(&pitch, goalPitch, 16); @@ -7539,7 +7534,7 @@ void cutscene_dance_fly_away_start(struct Camera *c) { c->nextYaw = c->yaw; } -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING // Restrict the camera yaw in tight spaces if ((gLastCompletedStarNum == 6) && (gCurrCourseNum == COURSE_CCM)) { star_dance_bound_yaw(c, 0x5600, 0x800); @@ -7553,7 +7548,7 @@ void cutscene_dance_fly_away_start(struct Camera *c) { if ((gLastCompletedStarNum == 3) && (gCurrCourseNum == COURSE_RR)) { star_dance_bound_yaw(c, 0x0, 0x800); } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING } void cutscene_dance_fly_away_approach_mario(struct Camera *c) { @@ -8082,12 +8077,12 @@ void cutscene_goto_cvar_pos(struct Camera *c, f32 goalDist, s16 goalPitch, s16 r nextPitch = goalPitch; vec3f_copy(sCutsceneVars[0].point, sCutsceneVars[3].point); sStatusFlags &= ~CAM_FLAG_SMOOTH_MOVEMENT; -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelNum == LEVEL_TTM) { nextYaw = atan2s(sCutsceneVars[3].point[2] - c->areaCenZ, sCutsceneVars[3].point[0] - c->areaCenX); } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING } else { if (c->cutscene == CUTSCENE_PREPARE_CANNON) { vec3f_get_dist_and_angle(c->pos, sCutsceneVars[0].point, &curDist, &curPitch, &curYaw); @@ -8365,14 +8360,14 @@ void cutscene_suffocation(struct Camera *c) { void cutscene_enter_pool_start(struct Camera *c) { vec3f_copy(sCutsceneVars[3].point, sMarioCamState->pos); -#ifdef ENABLE_VANILLA_LEVEL_SPECIFIC_CHECKS +#ifdef ENABLE_VANILLA_CAM_PROCESSING if (gCurrLevelNum == LEVEL_CASTLE) { // entering HMC vec3f_set(sCutsceneVars[3].point, 2485.f, -1589.f, -2659.f); } if (gCurrLevelNum == LEVEL_HMC) { // entering CotMC vec3f_set(sCutsceneVars[3].point, 3350.f, -4589.f, 4800.f); } -#endif +#endif // ENABLE_VANILLA_CAM_PROCESSING vec3f_copy(sCutsceneVars[0].point, c->focus); } @@ -10021,13 +10016,10 @@ struct Cutscene sCutsceneCredits[] = { * Cutscene that plays when Mario pulls open a door. */ struct Cutscene sCutsceneDoorPull[] = { -// HackerSM64 TODO: Properly transition when moving through doors -#ifndef FORCED_CAMERA_MODE { cutscene_door_start, 1 }, { cutscene_door_fix_cam, 30 }, { cutscene_door_move_behind_mario, 1 }, { cutscene_door_follow_mario, 50 }, -#endif { cutscene_door_end, 0 } }; @@ -10035,13 +10027,10 @@ struct Cutscene sCutsceneDoorPull[] = { * Cutscene that plays when Mario pushes open a door. */ struct Cutscene sCutsceneDoorPush[] = { -// HackerSM64 TODO: Properly transition when moving through doors -#ifndef FORCED_CAMERA_MODE { cutscene_door_start, 1 }, { cutscene_door_fix_cam, 20 }, { cutscene_door_move_behind_mario, 1 }, { cutscene_door_follow_mario, 50 }, -#endif { cutscene_door_end, 0 } }; @@ -10050,11 +10039,8 @@ struct Cutscene sCutsceneDoorPush[] = { * side. */ struct Cutscene sCutsceneDoorPullMode[] = { -// HackerSM64 TODO: Properly transition when moving through doors -#ifndef FORCED_CAMERA_MODE { cutscene_door_start, 1 }, { cutscene_door_fix_cam, 30 }, -#endif { cutscene_door_mode, CUTSCENE_LOOP } }; @@ -10063,11 +10049,8 @@ struct Cutscene sCutsceneDoorPullMode[] = { * side. */ struct Cutscene sCutsceneDoorPushMode[] = { -// HackerSM64 TODO: Properly transition when moving through doors -#ifndef FORCED_CAMERA_MODE { cutscene_door_start, 1 }, { cutscene_door_fix_cam, 20 }, -#endif { cutscene_door_mode, CUTSCENE_LOOP } };