rework vanilla camera overrides (#873)

This commit is contained in:
Anoliah
2025-10-30 19:20:47 -07:00
committed by GitHub
parent 8f4b5b99c9
commit cbd0c05447
3 changed files with 49 additions and 72 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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 }
};